# rounding a fractional number

Status
Not open for further replies.

#### mformazhar1980

##### Junior Member level 1
fractionary numbers

hi guys
i need to round of a number first and then Oring it with 128 can some one help me how to round of the fractional part thanks

signed int a;
unsigned int b;
unsigned int c;
if(c<b)
{
a=0.46*(b-c) | 128;
}

now if we suppose that b=460 and c=200 the expression 0.46*(b-c) then gives 119.6 so i need to round it to 120? and then Ored with 128 is it possible if so then how?

thanks
hussain

#### nandhu015

fractional number

Hai

it will be done automatically as you have declared "a" as integer

Nandhu

#### arthur0

##### Full Member level 2
fractional rounding

Well, Nandhu, it is true that the decimals will dissappear, but the result won't be rounded correctly. In the best case, it will be truncated, in the worst, it will be 0, depending on the implicit conversions assumed by the compiler.

For embedded I would rewrite the expression like this:
Code:
a=(((signed long)(0.46*100)*(b-c) + 50)/100) | 128
just to avoid having the compiler invoking the floating point library, or just to avoid a big 0, in case the floats are disabled and then 0.46 is reduced to an integer (0).
The "+50" is half of "100" and has the role of rounding (as opposed to truncating) to the nearest integer, after the division with 100.
In general, writing:
Code:
(float_var*kt + kt/2) / kt
yields a proper rounding.

For PC, i would write:
Code:
a=(signed int)(0.46*(b-c)+0.5) | 128
The "+0.5" has the same effect as "+50" above (i.e. 1.4 + 0.5 = 1.99 --> 1; 1.6 + 0.5 = 2.1 --> 2).

Arthur

#### mformazhar1980

##### Junior Member level 1
correctly round number bc

Arthur
i need to put this for embedded solution so if i gonna take this
For embedded I would rewrite the expression like this:

a=(((signed long)(0.46*100)*(b-c) + 50)/100) | 128
but still it is not giving me the result

in my case i have to do the following may be then my question will be more clear to you i need to condition the values below in the range between 100

to -100
and i am using atmega128 as target board
i have two limits that is HighLim=652 and LowLim=155
and the middle reference values are Ref_Hi=475 and Ref_Lo=372
the function should return the after checking the values between 1 to +100 and then
in case of negative values it should return -1 to -100.
but at the moment i can only get the +ve values in return the -Ve values are not conditioned properly (Maybe) thats why i am not getting these,
can u look at the function and suggest me what i gonna do to get correct values
thanks

char Validate_Value(uword Value)
{

char Ret_Val = 0;

uword HighLim = 652;
uword LowLim = 155 ;

uword Ref_Hi = 475;
uword Ref_Lo = 372;

ENTER_CRITICAL();

//scaling the value from -1 to -100 so that it should return a negative value (THIS PART IS NOT FUNCTIONING!!!)
if(Value < Ref_Lo)
{
Value=(((char)(0.46*100)*(Ref_Lo - Value) + 50)/100) | 128;
}
//scaling the value from 1 to 100 (THIS PART IS WORKING ok)

if(Value > Ref_Hi)
{
Value=(((0.56*100)*(Value- Ref_Hi) + 50)/100) + 1;
}
}

EXIT_CRITICAL();

return Ret_Val;
}

#### arthur0

##### Full Member level 2
wholly fractional numbers

Oh, of course you're not getting the expected result...
Let's see what you do here:
Code:
Value=(((char)(0.46*100)*(Ref_Lo - Value) + 50)/100) | 128;
First of all, your casting to char does a lot of damage due to overflow. It's like doing modulus with 256 on every number and after every operation and that severely limits the range of your operations.
Look in my post above: i casted to a long int just to avoid overflow and that's what you have to do as well.

Second, obtaining negative numbers it's not just a matter of setting the most significant bit (MSB) in a number!
Negative numbers are internally encoded as two's complement (see here: http://en.wikipedia.org/wiki/Two's_complement), which is tad more than just setting the MSB, but you don't have to know that because the machine will do the computations for you.

I'd do something like this:
Code:
if(Value < Ref_Lo && Value >= LowLim)
{
Value=(((int)(0.46*100)*(Value - Ref_Lo) - 50)/100);
}
Test it on paper for the extremes in the Value range then debug and see if it's the right thing to do.

Arthur

### mformazhar1980

Points: 2

#### mformazhar1980

##### Junior Member level 1
what is a fractional numbers

thanks alot Arthur it work for me.
i really missed that point to have a 2s complement,
hope i can get such good suggestions in future from you.

Status
Not open for further replies.

Replies
3
Views
1K
Replies
6
Views
14K
Replies
1
Views
3K
Replies
0
Views
2K
Replies
3
Views
874