float a;
a=8.3;
if(a==8.3)
printf("1");
else
printf("2");
分别给出 a 为 8.3 和 8.4 并相应地与 8.3 和 8.4 比较,输出变为 2,但与 8.5 比较时输出为 1。我发现它与需要 8 个字节的循环二进制的概念有关。我想知道如何找到哪个数字是循环二进制。请提供一些意见。
Recurring numbers are not representable, hence floating point comparison will not work.
Floating point math is not exact. Simple values like 0.2 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Also as in the 2nd comment - floating point literals 8.3
has type double
and a
has type float
.
Comparing with epsilon – absolute error
Since floating point calculations involve a bit of uncertainty we can try to allow for this by seeing if two numbers are ‘close’ to each other. If you decide – based on error analysis, testing, or a wild guess – that the result should always be within 0.00001 of the expected result then you can change your comparison to this:
if (fabs(result - expectedResult) < 0.00001)
For example, 3/7
is a repeating binary fraction, its computed value in double precision is different from its stored value in single precision. Thus the comparison 3/7
with its stored computed value fails.
For more please read - What Every Computer Scientist Should Know About Floating-Point Arithmetic
您不应使用 比较浮点数是否相等==
。由于浮点数实际存储在内存中的方式,它会给出不准确的结果。
使用类似这样的方法来确定您的数字a
是否足够接近所需的值:
if(fabs(a-8.3) < 0.0000005))
这里有两个问题。
首先是浮点字面量,比如8.3
have type double
, while a
has type float
。Doubles 和 floats 以不同的精度存储值,对于没有精确浮点表示的值(例如8.3
),存储的值略有不同。因此,比较失败。
您可以通过将比较编写为来解决此问题a==8.3f
;f
后缀强制文字为 a而float
不是 a double
。
但是,直接比较浮点值是不好的。同样,大多数值不能精确表示,而只能表示近似值。如果a
是涉及多个浮点计算的表达式的结果,它可能不等价于8.3f
. 理想情况下,您应该查看两个值之间的差异,如果它小于某个阈值,那么它们实际上是等效的:
if ( fabs( a - 8.3f) < EPSILON )
{
// a is "equal enough" to 8.3
}
的确切值EPSILON
取决于许多因素,其中最重要的是要比较的值的大小。您只有这么多位精度,因此如果您尝试比较的值大于 999999.0,那么您无法测试彼此之间 0.000001 以内的差异。