简体   繁体   中英

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?

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)

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 (eg 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

== performs an equality check. Equality checks are problematic with floats (see http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm)

So, once you get a false and once you get a true (1).

For a more robust way of comparing floats see - What is the most effective way for float and double comparison?

The difference is that 3.5 can be represented exactly as a binary floating point number, while 3.3 cannot.

Since the mathematical 3.3 cannot be exactly represented, 3.3 , as a double precision number, is a better approximation than the single precision number (float)3.3 , and therefore has a different value.

Why is there a difference in output?

A theoretical, but probably unsatisfying answer wearing a Math / CS ( ) hat is:

  • Because floating point numbers are finite, and thus not equal to the R http://mathurl.com/mgwavz7 numbers we are use to in mathematics (and much of the real world).
  • Floating point numbers are binary as opposed to decimal, so some fractions that are finite in decimal representation, but are repeating or transcendental (like Pi http://mathurl.com/62kzla or the base of the natural logarithm e ) in binary (or radix 2).

@Jens

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM