2016-03-26 73 views
0

我做了一個程序,將一個數字拆分成數字,當添加時,給出第一個數字。例如,1234應分爲1000,200,30,和4使用pow()函數時的不準確性

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 

int main() 
{ 
int i, num1, num2; 
char tmp[6]; // the number will be stored here as string 
int num3 = 12345; //the number 

sprintf(tmp, "%d", num3); //convert to string 
for(i = 0; i < strlen(tmp); i++) //check every digit 
{ 
    num1 = pow(10, strlen(tmp) - 1 - i); //every number will be multiplied by 10 
          //to the power of number of digits - 1 - counter 
    num2 = tmp[i] - '0'; //convert character to int 
    printf("%d\n", num1*num2); //print the number 
} 

return 0; 
} 

這是輸出:

9999 
2000 
297 
40 
5 

正如你可以看到這是不正確的,爲什麼呢?

+1

您發佈的版本似乎按原樣工作http://ideone.com/K3pY8r – xvan

+2

因爲'pow'包含浮點表示形式的錯誤。 – BLUEPIXY

+0

我在多個在線編譯器上試過了,它確實有效,但它在我的PC上無法正常工作。我該如何避免這種錯誤? – user3711671

回答

-1

問題是浮點計算可能有小錯誤。也就是說,pow函數的結果可能會比預期的稍大或略小。當您轉換爲int時,結果將被截斷。例如,如果pow(10,4)返回9999.999999,則轉換爲int會產生9999,這不符合您的預期。另一方面,如果pow(10,3)返回1000.000001然後轉換爲int將給出預期的結果。

下面是一些代碼,應表現出的問題(計算機上,其中pow函數的結果可能不準確):

int main(void) 
{ 
    for (int i = 0; i < 5; i++) 
    { 
     double num1 = pow(10,i); 
     int num2 = num1; 
     printf("%12f --> %5d\n", num1, num2); 
    } 
} 

爲了避免這個問題,您可能需要一輪pow的結果,或完全避免浮點數學。下面的代碼展示瞭如何僅使用整數數學來解決問題。

int main(void) 
{ 
    char temp[] = "12345"; 
    int length = strlen(temp); 

    int multiplier = 1; 
    for (int i = 1; i < length; i++) 
     multiplier *= 10; 

    for (int i = 0; i < length; i++) { 
     printf("%d\n", (temp[i] - '0') * multiplier); 
     multiplier /= 10; 
    } 
} 
+0

Multi-dup。 ............ –