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