2010-10-22 37 views
0
void main() 
{ 
    char buffer[40]; 
    float x=1.2f,y=.2f; 
    printf("%f",(x/y)); 
    printf("\n%s\n", gcvt(x/y, 30, buffer));   
} 

第二個printf結果爲6.0000001490116102.I預計答案是6.0000 ...全零。C中的gcvt函數的幫助?

+1

既然你說它是C,它*是* C,爲什麼要標記它Objective-C? – BoltClock 2010-10-22 09:24:35

回答

1

全部浮點問題,一些數字不能完全表示。習慣了這一點,這是生活中的一個事實:-)

對於32位浮點值(例如),可以精確地表示大約40億個數字。不幸的是,在數學中,即使在00.00000000000000000000001之間,也有,嗯...,讓我想想,一個無限數

有一點你可能找到有用的是使用雙打而不是浮動 - 他們有更多的位,因此可以代表更準確的數字。除此之外,如果你想要更精確的話,可以使用任意的精度庫。

如果你改變你的代碼(包括一個體面main):

int main (void) { 
    char buffer[40]; 
    float x=1.2f,y=.2f; 
    double xd=1.2,yd=.2; 

    printf("%f\n",(x/y)); 
    printf("%.30f\n",(x/y)); 
    printf("%s\n\n", gcvt(x/y, 30, buffer)); 

    printf("%f\n",(xd/yd)); 
    printf("%.30f\n",(xd/yd)); 
    printf("%s\n", gcvt(xd/yd, 30, buffer)); 
} 

,你會在行動中看到這一點:

6.000000 
6.000000149011610162119723099750 
6.00000014901161016211972309975 

6.000000 
5.999999999999999111821580299875 
5.99999999999999911182158029987 

你可以看到,雙打更接近你期望值,但它們仍然不準確。 IEEE754雙精度大約有16位精度(單精度浮點數約爲7)。

0

由於paxdiabolo建議,查看浮點運算以瞭解發生了什麼。但同時,我man頁面上有一個重要的暗示:

此功能在 POSIX.1-2001標記爲LEGACY。 POSIX.1-2008刪除 gcvt()的規格, 建議使用sprintf(3) 來代替(儘管snprintf(3)可能最好是 )。

所以只是不要使用它。