c-使用pow()函数时不准确



我制作了一个程序,将一个数字拆分为多个数字,相加后给出第一个数字。例如,1234应分为1000、200、30和4。

#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("%dn", num1*num2); //print the number
}
 return 0;
}

这是输出:

9999
2000
297
40
5

正如你所看到的,这是不正确的,为什么?

问题是浮点计算可能会有小误差。也就是说,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 --> %5dn", 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( "%dn", (temp[i] - '0') * multiplier );
        multiplier /= 10;
    }
}

最新更新