Floating point numbers are not exact

The computer’s interior cannot be accurately expressed as a binary decimal.

Public class Tesz {public static void main(String[] args) {double a = 0.1; Float c = 0.1 f; System.out.println(a==c); // print false}}Copy the code

  • If either side of the operator is of type double, the other side is converted to double
  • Otherwise, if either side of the operator is of type float, the other side is converted to float
  • Otherwise, if either side of the operator is of type long, the other side is converted to long
  • Otherwise, both sides will be converted to int

According to IEEE 754, single-precision floats are 32 bits and double-precision doubles are 64 bits

The first part (s) is the sign bit, the second part (Exponent) is the exponent bit, and the third part (mantissa) is the radix part. This is the binary representation of scientific notation.

  • Like 3.1415926…. Or infinitesimally, infinitesimally, it will cancel out the part that can’t be identified.
  • Binary cannot accurately represent floating point numbers

Why can’t binary accurately represent floating point numbers

Println (integer.toBinaryString (float.floatToIntbits (0.1f))); The result is: 111101110011001100110011001101Copy the code

Binary system.out.println (long.tobinaryString (doubleToLongBits(0.1d))); The result is: 11111110111001100110011001100110011001100110011001100110011010Copy the code

System.out.println(long.tobinaryString (doubleToLongBits(0.1f))); Result: 11111110111001100110011001100110100000000000000000000000000000 is obviously differentCopy the code

The representation of a binary decimal

According to the international standard IEEE 754, any binary floating point number V can be expressed in the following form:

(1) (-1)^s indicates the sign bit, when s=0, V is positive; When s is equal to 1, V is negative.

(2) M represents a significant number, greater than or equal to 1 and less than 2.

(3) 2^E represents the exponent bit.

An example is the binary representation of 0.2 in decimal

0.01 = 1/4 = 0.25, too large 0.001 =1/8 = 0.125, too small 0.0011 =1/8 + 1/16 = 0.1875, 0.00111 = 1/8 + 1/16 + 1/32 = 0.21875, 0.0011001 = 1/8+ 1/16 + 1/128 = 0.1953125 1/8 + 1/16 + 1/128 + 1/256 = 0.19921875...Copy the code

The first method: convert to a string

If the string precision of the two floating-point data to be compared is equal, we can convert the data to string and then use string’s equals method to indirectly compare two double data to be equal. Note that this method can only be used to compare data with the same precision, and it is only used to compare whether the data is equal, not to judge the size.

Float. ToString (453.2348 f) equals (Float. ToString (0.342 f)). Double toString (0.8456 d) equals (Float. ToString (0.242 f))Copy the code

The second method: use the doubleToLongBits() method provided by Sun

This method converts a double to a long, which makes it possible for a double to determine size and equality according to long’s methods (<, >, ==).

DoubleToLongBits (0.01) == doubleToLongBits(0.01) doubleToLongBits(0.02) > Double Double. DoubleToLongBits (0.01). The doubleToLongBits (0.02) < Double. DoubleToLongBits (0.01)Copy the code

The third method: intra-error comparison

Double d1=0.0000001, double d2=0d For example, d1=0.0000001, d2=0d

if(d1==d2)

.

Fourth method: BigDecimal type

Double a = 0.001; Double b = 0.0011; BigDecimal data1 = new BigDecimal(a); BigDecimal data2 = new BigDecimal(b); Data1.com pareTo(data2) is a non-integer number. It is recommended to use BigDecimal because the operation may be inaccurate.Copy the code

Counterexample 1: Is it ok to use equals

Double a = Double. The valueOf (" 0.0 "); Double b = Double. The valueOf (" 0.0 "); System.out.println(a.equals(b)); False Double a = math.sqrt (-1.0); Double b = 0.0d / 0.0d; Double c = a + 200.0d; Double d = b + 1.0d; System.out.println(a.equals(b)); System.out.println(b.equals(c)); System.out.println(c.equals(d)); true true trueCopy the code

The equals method compares whether two objects are equal, not whether their values are equal

Counterexample 2: Is it ok to use the compareTo method

Public static void main(String[] args) {Double a = Double. ValueOf ("0.0"); Double b = Double. The valueOf (" 0.0 "); System.out.println(a.compareTo(b)); //1 Double a1 = math.sqrt (-1.0); Double b1 = 0.0d / 0.0d; Double c1 = a1 + 200.0d; Double d1 = b1 + 1.0d; System.out.println(a1.compareTo(b1)); System.out.println(b1.compareTo(c1)); System.out.println(c1.compareTo(d1)); / / / / / / 0 0 0}Copy the code

A and b represent NaN(Not a Number).

conclusion

There are three main factors to consider when comparing floating point numbers

  • NaN
  • Infinity/infinitesimal
  • Rounding error

So, to compare floating point numbers for equality, here’s what you need to do:

  • Exclude NaN and infinity
  • Make a comparison within the accuracy range

Refer to the connection

Blog.csdn.net/renwotao200…

En.wikipedia.org/wiki/Floati…

Blog.csdn.net/wcxiaoych/a…

www.ruanyifeng.com/blog/2010/0…

Pay attention to the public account “Programmer interview”

Reply to “interview” to get interview package!!

This public account to share their own from programmer xiao Bai to experience spring recruitment autumn recruitment cut more than 10 offer interview written test experience, including [Java], [operating system], [computer network], [design mode], [data structure and algorithm], [Dacheng face by], [database] look forward to you join!!

1. Computer network —- Three times shake hands four times wave hands

2. Dream come true —– Project self-introduction

Here are the design patterns you asked for

4. Shocked! Check out this programmer interview manual!!

5. Teach you the interview “Profile” word for word

6. Nearly 30 interviews shared

7. Here are the free books you asked for