0

I have the following code,

float a = 0.7;
if(0.7 > a)
    printf("Hi\n");
else
    printf("Hello\n");   //Line1

and

float a = 0.98;
if(0.98 > a)
    printf("Hi\n");
else
    printf("Hello\n");   //Line2

here line1 outputs Hi but Line2 outputs Hello. I assume there would be a certain criteria about double constant and float, i.e any one of them would become larger on evaluation. But this two codes clarify me that situation can be come when double constant get larger and some other times float get larger. Is there any rounding off issue behind this? If it is, please explain me. I am badly in need of this clear.. thanks advance

mskfisher
  • 3,291
  • 4
  • 35
  • 48
amin__
  • 1,018
  • 3
  • 15
  • 22
  • There are several questions regarding floating point round off. Please look at these, because this is the cause of your issues. – Starkey Jul 10 '12 at 21:20
  • `0.7` and `0.98` are values of type `double`. When you compare a value of type `double` with a value of type `float`, the value of type `float` is converted to type `double`. **The initial conversion of `0.7` or `0.98` to float loses precision**, once making the number larger and the other time making it smaller. Try this: `float a = 0.7f; if (a < 0.7f) /* ... */;` – pmg Jul 10 '12 at 21:21
  • Many, many duplicates, e.g. [Floating point comparison `a != 0.7`](http://stackoverflow.com/questions/6883306/floating-point-comparison-a-0-7) and [problems in floating point comparison](http://stackoverflow.com/questions/3962724/problems-in-floating-point-comparison). – Paul R Jul 10 '12 at 21:38

4 Answers4

11

What you have is called representation error.

To see what is going on you might find it easier to first consider the decimal representations of 1/3, 1/2 and 2/3 stored with different precision (3 decimal places or 6 decimal places):

a = 0.333
b = 0.333333
a < b

a = 0.500
b = 0.500000
a == b

a = 0.667
b = 0.666667
a > b

Increasing the precision can make the number slightly larger, slightly smaller, or have the same value.

The same logic applies to binary floating point numbers.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
4
float a = 0.7;

Now a is the closest single-precision floating point value to 0.7. For the comparison 0.7 > a that is promoted to double, since the type of the constant 0.7 is double, and its value is the closest double-precision floating point value to 0.7. These two values are different, since 0.7 isn't exactly representable, so one value is larger than the other.

The same applies to 0.98. Sometimes, the closest single-precision value is larger than the decimal fraction and the closest double-precision number smaller, sometimes the other way round.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • is there any easy way to understand which way round off can go?? – amin__ Jul 10 '12 at 21:32
  • Yes and No. Yes: it can go both ways. No: you need to know enough bits in the binary representation to see which way it goes, apart from a few trivial cases (0.5 etc.), that's not easily seen from the decimal representation. You can reduce the number of surprises by sticking to `double` for all variables, but even then, the implementation is allowed to use an internal representation with higher precision. – Daniel Fischer Jul 10 '12 at 21:36
3

This is part of What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Idelic
  • 14,976
  • 5
  • 35
  • 40
1

This is simply one of the issues with floating point precision.

While there are an infinite number of floating point numbers, there are not an infinite number of floating point representations due to the bit-constraints. So there will be rounding errors when using floats in this manner.

There is no criteria for where it decides to round up or down, that would probably be language -implementation or compiler dependent.

See here: http://en.wikipedia.org/wiki/Floating_point, and http://en.wikipedia.org/wiki/IEEE_754 for more details.

ardent
  • 2,453
  • 1
  • 16
  • 15