Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

rounding a fractional number

Status
Not open for further replies.

mformazhar1980

Junior Member level 1
Joined
Mar 23, 2009
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,436
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

Advanced Member level 5
Joined
Feb 11, 2006
Messages
1,965
Helped
300
Reputation
600
Reaction score
224
Trophy points
1,353
Location
India
Activity points
9,845
fractional number

Hai

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

Nandhu
 

arthur0

Full Member level 2
Joined
Nov 28, 2003
Messages
131
Helped
49
Reputation
98
Reaction score
36
Trophy points
1,308
Location
Stockholm, Sweden
Activity points
1,218
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
Joined
Mar 23, 2009
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,436
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;
ubyte Mask = 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;
Mask =Value;
}
//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;
Mask = Value;
}
}


Ret_Val |= Mask;

EXIT_CRITICAL();

return Ret_Val;
}
 

arthur0

Full Member level 2
Joined
Nov 28, 2003
Messages
131
Helped
49
Reputation
98
Reaction score
36
Trophy points
1,308
Location
Stockholm, Sweden
Activity points
1,218
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); 
   Mask =Value; 
}
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

Junior Member level 1
Joined
Mar 23, 2009
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,436
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.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top