0

While rounding off the floating point values I observed some discrepancy in values. I have extracted following part of code. Here if variable var_d is assigned value> 5.3 to then I am getting proper values for variable var_d, but for values like 5.01 and 5.02 I am getting 500 and 501 respectively.

#include<stdio.h>
int main()
{
double var_d=5.02;
long var_l;
var_l = (double)(var_d*100);
printf("var_d : %f  var_l= %ld\n ",var_d,var_l);
printf("result : %ld\n",var_l);
return 0;
}
aashoo
  • 404
  • 4
  • 13
  • I am using GCC Version 4.3.2 on SUSE Linux. – aashoo May 16 '13 at 11:59
  • Rounding up floating point values is bound to a certain degree of unpredictability. Fixed point arithmetics should be used instead. – Alex May 16 '13 at 11:59
  • possible duplicate of [Floating point inaccuracy examples](http://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples) – AndersK May 16 '13 at 12:01
  • 1
    @Alex This has much more to do with the choice of a base than with the choice of fixed/floating point. Binary floating-point fails at these examples. With reasonable parameters, decimal floating-point gets these examples right. Binary fixed-point fails at these or similar examples. With reasonable parameters, decimal fixed-point gets these examples right. – Pascal Cuoq May 22 '13 at 09:43
  • Indeed it would be nice if C had BCD (binary coded decimal) float types, even if they had to be done in software. – Adrian Ratnapala Jun 13 '13 at 14:59

2 Answers2

2

Use

double var_d=5.02;
long var_l = rint(var_d*100);

Since 100 * 5.02 is not not exactly equal to 502, you are getting a rounded down.

To be clearer: 5.02 has no exact representation in binary floating point. Thus var_l*100 == 5.02*100 is not exactly 502. In fact it is closer to 501.99999999999994. When you cast it to an integer, this is rounded down to 501.

Adrian Ratnapala
  • 5,485
  • 2
  • 29
  • 39
-1
float var_d=5.02;
long var_l;
var_l = (long)(float)(var_d*100);

This should works properly

  • I tried it but it does not work, Instead I used following var_l = (float)(var_d*100) + 1e-9 ; which is working for now. – aashoo May 17 '13 at 05:35