Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

floating point numbers equality checking

With the following code,

#include <stdio.h>

int main(void){
  float x;
  x=(float)3.3==3.3;
  printf("%f",x);
  return 0;
}

the output is 0.00000

but when the number 3.3 is replaced with 3.5,

#include <stdio.h>

int main(void){
  float x;
  x=(float)3.5==3.5;
  printf("%f",x);
  return 0;
}

the output is 1.0000

Why is there a difference in output?

like image 523
Gabriela Jennifer Avatar asked Nov 29 '22 15:11

Gabriela Jennifer


2 Answers

You should understand that in C the literal 3.3 has type double. Converting a double to a float may lose precision, so the comparison of 3.3F with 3.3 yields false. For 3.5 the conversion is lossless since both can be represented exactly and the comparison yields true.

It's somewhat related to (in base 10 instead of base 2) comparing

3.3333333 with 3.3333333333333333  (false)
3.5000000 with 3.5000000000000000  (true)
like image 61
Jens Avatar answered Dec 17 '22 05:12

Jens


Due to rounding errors, most floating-point numbers end up being slightly imprecise. As long as this imprecision stays small, it can usually be ignored. However, it also means that numbers expected to be equal (e.g. when calculating the same result through different correct methods) often differ slightly, and a simple equality test fails.

And in your case, converting a double to float loses some precision.

You have to be very careful when you compare floating-points.

I suggest you to take a look at this link: What is the most effective way for float and double comparison?

This article may help you to understand why it appends : http://www.cprogramming.com/tutorial/floating_point/understanding_floating_point_representation.html


A little explanation about floating-point numbers and why this is happening :

Floating-point numbers are typically packed into a computer datum as the sign bit, the exponent field, and the significand (mantissa), from left to right.

Basically, you can say that a floating-point number is :

number = (sign ? -1:1) * 2^(exponent) * 1.(mantissa bits)

Of course, depending on if you are using a float or a double, the precision is different :

          | Sign | Exponent | Significand | Total bits
float     | 1    | 8        | 23          | 32
Double    | 1    | 11       | 52          | 64

Here you can see why you may lose some data by converting a double to float.

In you case, it seems that the computer is able to compute 3.5 exactly, but not 3.3. Somehow, with the formula, we may assume that you are doing something like :

3.3333333 == 3.333333333333333   // is false because of the precision
3.5000000 == 3.500000000000000   // is true

// I tried to match the precision of the float in the left
// and the precision of the double on the right
like image 23
Pierre Fourgeaud Avatar answered Dec 17 '22 06:12

Pierre Fourgeaud