匯出 (0) 列印
全部展開
本文章是由人工翻譯。 將指標移到文章內的文字上方即可查看原文。 其他資訊。
譯文
原文

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

一般而言,十進位浮點數值並沒有精確的二進位表示式。 這是 CPU 表示浮點資料方式的副作用 (Side Effect)。 因為這個原因,可能會失去一些精確度,且某些浮點作業可能產生未預期的結果。

下列其中一項因素造成這種行為:

  • 十進位數字的二進位表示式可能不精確

  • 使用的數字之間出現型別不符的情形,(例如,混用浮點數 (Float) 和雙精度浮點數 (Double)。

為了解決這種行為,大部分的程式設計人員可能會確保此值大於或小於其所需的值,或是取得並使用 BCD (Binary Coded Decimal) 程式庫來保持精確度。

浮點值的二進位表示會影響浮點計算的精確度和正確性。 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);
}
它們並不相等!   c 的值為 2.4679999352 或 2.468000  

若為 EPSILON,您可使用常數 FLT_EPSILON (其被定義為浮點 1.192092896e-07F) 或 DBL_EPSILON (其被定義雙精度 2.2204460492503131e-016); 您必須對這些常數併入 float.h。 這些常數被定義為最小的正數 x,而 x+1.0 不等於 1.0。 由於這是一個非常小的數字,因此在涉及極大數字的計算時,應採用使用者定義的容錯度。

社群新增項目

新增
顯示:
© 2015 Microsoft