2016-04-22 73 views
1

下面是一個簡單的C++程序的代碼:原因是C怪輸出++程序

#include <bits/stdc++.h> 
using namespace std; 

int main() { 
    double x = 3; 
    double y = .15; 
    while(x>0) { 
     printf("%.15f ",x); 
     cout<<x<<endl; 
     x-=y; 
    } 
    return 0; 
} 

輸出:

> 3.000000000000000 3 
> 2.850000000000000 2.85 
> 2.700000000000000 2.7 
> 2.550000000000000 2.55 
> 2.400000000000000 2.4 
> 2.250000000000000 2.25 
> 2.100000000000001 2.1 
> 1.950000000000001 1.95 
> 1.800000000000001 1.8 
> 1.650000000000001 1.65 
> 1.500000000000001 1.5 
> 1.350000000000001 1.35 
> 1.200000000000001 1.2 
> 1.050000000000001 1.05 
> 0.900000000000001 0.9 
> 0.750000000000001 0.75 
> 0.600000000000001 0.6 
> 0.450000000000001 0.45 
> 0.300000000000001 0.3 
> 0.150000000000001 0.15 
> 0.000000000000001 1.05471e-15 

看看現在的第七行。這不奇怪嗎?這裏出於某種原因2.25 - .15正在2.100000000000001。我知道這可以通過使用浮動來避免。但我想知道爲什麼會發生這種情況。

+1

浮點數不能精確存儲,因爲並非所有的十進制數都有二進制的精確表示。這就是所謂的浮點錯誤,也是爲什麼你應該總是非常謹慎的事情,例如測試兩個相等的浮點數 – dww

回答

0

你的問題說明了浮點錯誤 - 正如dww所描述的那樣。

因爲計算機是二進制的,所以如果它們的位數超過一定數量,它們就不會精確地存儲浮點數。

爲了說明,整數以二進制非常精確地存儲。 8位,0000 0000,可以表示2^8個值,或0-256。 16位,0000 0000 0000 0000,可以表示2^16個值,或0-65536。負值是使用2的恭維來存儲的,所以存儲與正數一樣精確。

請注意,沒有一個整數需要「浮點」來表示。

由於點的位置決定了確切的值,所以浮點很難表示,並且可能會顯示在不同的位置。如果有16個數字位置,0000000000000000,則浮點可以在任何沿線。 16.00027562809373可以表示爲756352.8363578476或0.000000000000001。

但是像浮點數一樣,浮點數的值是有限的。在您的輸出中,它看起來像任何超出範圍的數字0.000000000000001 < x < 999999999999999.9無法準確表示,也不能將有效數字> 2^52(浮點數)存儲在64位存儲器中。

因爲你的有效位域是16位數字,所以我猜這就是你輸出的域寬。 (我不能猜測你正在運行什麼系統,因爲這也決定了你的計算機的浮點精度,這意味着一個64位系統比32位系統具有更高的精確度。)

在64位系統中,一個浮點數將在內存中具有這種結構:

0 | 000 0000 00000 | 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

^---------------^---------------- --------------------------------------------^----- -----------------------------------------

+/-_____ exponent_____________________________significand___________________

有效數字是存儲的數字,指數決定浮點的位置,而符號決定它是正數還是負數。

末尾的'1'表示計算機認爲存在一些小於0.000000000000001的值,但它正在四捨五入。最後,這個數字非常小,接近零,它表示爲0.000000000000001 1.05471e-15;等於0.00000000000000105471,仍然是正數。