共用方式為


浮點數會失去精確度的原因

浮點十進位值通常沒有確切的二進位標記法。 這是 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。 因為這是非常少量的數位,因此您應該針對涉及非常大量的計算,採用使用者定義的容錯。

另請參閱

最佳化程式碼