[英]How precision of floating-point works exactly in practical examples?
I thought that float precision is 7 decimal places/digits (including both integer and decimal part) - here I mean base10 7 digits - I can type those 7 digits in my floating-point literal in my code editor. 我认为浮点精度是7个小数位/数字(包括整数和小数部分)-在这里我的意思是base10 7个数字-我可以在代码编辑器中的浮点文字中键入这7个数字。 It means that if I have 7 significant digits (before and after decimal point) in two numbers, those two numbers shall be always different.
这意味着如果我在两个数字中有7个有效数字(小数点前后),则这两个数字应始终不同。
But as I see, two numbers with 7 significant digits sometimes differ, and sometimes same!!! 但是,正如我所看到的,两个具有7个有效数字的数字有时会有所不同,有时甚至相同!!!
1) Where am I wrong? 1)我哪里错了?
2) What is the pattern and principle in examples below? 2)以下示例的模式和原理是什么? Why same 7-digit-precision combinations sometimes are treated as different, and other times are treated as being the same?
为什么有时将相同的7位数精度组合视为不同,而有时将其视为相同?
float f01 = 90.000_001f;
float f02 = 90.000_002f; // f01 == f02 is TRUE ! (CORRECT RESULT)
float f03 = 90.000_001f;
float f04 = 90.000_003f; // f03 == f04 is TRUE ! (CORRECT RESULT)
float f1 = 90.000_001f;
float f2 = 90.000_004f; // FALSE (INCORRECT RESULT)
float f3 = 90.000_002f;
float f4 = 90.000_009f; // FALSE (INCORRECT RESULT)
float f5 = 90.000_009f;
float f6 = 90.000_000f; // FALSE (INCORRECT RESULT)
float f7 = 90.000_001f;
float f8 = 90.000_009f; // FALSE (INCORRECT RESULT)
Seven decimal places is a convenient rule of thumb, but it's not what's really going on. 小数点后七个位是一个方便的经验法则,但这并不是真正的事情。 Java's
float
is a 32-bit binary floating point format, following the IEEE-754 standard . Java的
float
是遵循IEEE-754标准的32位二进制浮点格式 。 The encoding has 1 sign bit, 23 bits for the mantissa and 8 for the exponent, so your value is in scientific notation, in binary: 编码有1个符号位,尾数为23位,指数为8位,因此您的值采用科学计数法,采用二进制:
f = +/- mantissa * 2^exponent
Converting your values into this format you should be able to see what's happening: 将您的值转换为这种格式,您应该能够看到正在发生的事情:
90.000001 = 0(sign) 10000101(exponent) 01101000000000000000000(mantissa)
90.000003 = 0(sign) 10000101(exponent) 01101000000000000000000(mantissa)
90.000004 = 0(sign) 10000101(exponent) 01101000000000000000001(mantissa)
This is a handy tool for comparing encoded values if you'd like to explore further: https://www.h-schmidt.net/FloatConverter/IEEE754.html 如果您想进一步探索,这是一个比较编码值的便捷工具: https : //www.h-schmidt.net/FloatConverter/IEEE754.html
In practice, the solution to this is that you should never use the ==
operator to compare floating point values, always compare floats with a precision: 实际上,解决方案是永远不要使用
==
运算符比较浮点值,始终以精度比较浮点数:
Math.abs(x - y) < epsilon
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.