Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Rounding float 1

Status
Not open for further replies.

Deckster

IS-IT--Management
Aug 21, 2003
9
US
Hello all, I'm trying to round to the 100th with the below macro. Seems to work ok until the value is passed back to main(). Any help would be much appreciated.


float RoundVal(float);

float fault_miles = 0.00;
fault_miles=RoundVal(fault_miles);


float RoundVal(float num)
{
float temp = 0.0;
int i=0;

temp = num;
temp = temp * 100;
temp = temp + 0.50;
i = (int)temp;
printf("%d\n", i);
temp = (i/100.00);
printf("\n%f\n", temp);
return temp;
}

 
How about something like...
Code:
#include <math.h>

float RoundVal(float num)
{
  return((float)(floor((double)(num * 100.0)) / 100.0));
}
This is basically doing the same thing you are but using the math library function [tt]float()[/tt]. The function [tt]float()[/tt] takes and returns a double, so that's why the cast to and from a double.

Hope this helps.

 
floats by their nature are approximations

If your real answer is 123.45 and that is not a representable float, you will always get the nearest approximation of that
123.4499
124.4501

floats have 6 decimal digits of precision. Given that you have two digits for the 100th's, it doesn't give you a lot of room for everything else.

doubles on the other hand have 15 decimal digits of precision, which should be enough for most purposes. But remember, they're still approximations, so the representation problem has merely been put back rather than solved.

--
 
My personal inclination is actually to keep full precision for whatever variable type you use (float, double as appropriate) until you are ready to print the answer. Then, rather than rounding the float, create a string with the appropriate number of decimal points.

Yes Salem, doubles are vastly better; but Beware All Who Tread This Path! A numerically unstable method should not be rescued by conversion to double, because all that does is push the problem into the future. Yes, for now the answer looks better, but there may still be an underlying problem in the calculation (e.g. you're subtracting a very large number from an almost identical large number and relying on the difference, which will have very poor precision). This underlying problem will surface another day when the input data are different. The right approach is to change the way the calculation is carried out. For people like me, with very limited numerical knowledge, that usually means finding a good book.

Actually, on the matter of accurate representation of decimals in binary you can have a lot of fun with Excel. If you divide 1 by 3 it will give you 15 decimal places of 0.3 followed by zeroes (because that is the internal precision of Excel, at least the version I have). You will need to expand the column width to see this. You can also type fifteen decimal places of 0.3. They will look the same. But if you multiply the original by 3 it returns to 1, whereas the typed version goes to fifteen places of 0.9...
 
Thanks for the posts. But, I'm still getting an output problem when the value is returned to main(). Here's an example when using &quot;.17&quot; (w/o quotes).

Enter Fault Miles> 9.955
THIS IS THE VAL INSIDE THE FUNCTION:9.955000
Output: 9.950000

Seems to me that the value should be 9.96

Here's the function/macro...

float RoundVal(float num)
{
printf(&quot;THIS IS THE VAL INSIDE THE FUNCTION:%f\n&quot;, num);
return((float)(floor(((double)(num * 100.0) + 0.5)) / 100.0));
}
 
> return((float)(floor(((double)(num * 100.0) + 0.5)) / 100.0));
Trying to do too much at once?

Code:
#include <stdio.h>
#include <math.h>

typedef float type;

type RoundVal(type num)
{
    printf(&quot;Input:%f\n&quot;, num);
    num *= 100;
    printf(&quot;step 1:%f\n&quot;, num);
    num += 0.5;
    printf(&quot;step 2:%f\n&quot;, num);
    num = floor( num );
    printf(&quot;step 3:%f\n&quot;, num);
    num /= 100.0;
    printf(&quot;step 4:%f\n&quot;, num);
    return num;
}

int main ( ) {
    type    a = 9.955;
    printf( &quot;Old=%f, new=%f\n&quot;, a, RoundVal(a) );
    return 0;
}

Input:9.955000
step 1:995.500000
step 2:996.000000
step 3:996.000000
step 4:9.960000
Old=9.955000, new=9.960000

--
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Sponsor

Back
Top