浮點數會失去精確度的原因
浮點十進位值通常沒有確切的二進位表示法。 這是 CPU 代表浮點數據的副作用。 基於這個理由,您可能會遇到一些精確度遺失的情況,而某些浮點運算可能會產生非預期的結果。
此行為是下列其中一項的結果:
十進位數的二進位表示法可能不精確。
所使用的數字之間有類型不符(例如混合浮點數和雙精度浮點數)。
若要解決此行為,大部分程式設計人員都會確保值大於或小於所需的值,或是取得並使用將維持精確度的二進位自動程式化十進位連結庫。
浮點值的二進位表示會影響浮點計算的精確度和精確度。 Microsoft Visual C++使用 IEEE 浮點格式。
範例
// Floating-point_number_precision.c
// Compile options needed: none. Value of c is printed with a decimal
// point precision of 10 and 6 (printf rounded value by default) to
// show the difference
#include <stdio.h>
#define EPSILON 0.0001 // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
int main() {
float a, b, c;
a = 1.345f;
b = 1.123f;
c = a + b;
// if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
if (c == 2.468) // Comment this line for correct result
printf_s("They are equal.\n");
else
printf_s("They are not equal! The value of c is %13.10f "
"or %f",c,c);
}
They are not equal! The value of c is 2.4679999352 or 2.468000
註解
針對 EPSILON,您可以使用常數 FLT_EPSILON,其定義為 float 1.192092896e-07F 或 DBL_EPSILON,其定義為 double 為 2.22204460492503131e-016。 您必須包含這些常數的 float.h。 這些常數定義為最小正數 x,因此 x+1.0 不等於 1.0。 因為這是非常少量的數位,因此您應該針對涉及非常大量的計算,採用使用者定義的容錯。