pow功能的奇怪行为。

时间:2022-05-07 13:50:51

While running the following lines of code:

运行以下代码行:

int i,a;    for(i=0;i<=4;i++)  {        a=pow(10,i);        printf("%d\t",a);    }   

I was surprised to see the output, it comes out to be 1 10 99 1000 9999 instead of 1 10 100 1000 10000.

我惊讶地看到输出,结果是1 10 99 1000 9999而不是1 10 100 1000 10000。

What could be the possible reason?

可能的原因是什么?

Note
If you think it's a floating point inaccuracy that in the above for loop when i = 2, the values stored in variable a is 99.

注意,如果您认为它是浮点型不精确,那么在上面的for循环中,当i = 2时,变量a中的值是99。

But if you write instead

但是如果你写的话

a=pow(10,2);

now the value of a comes out to be 100. How is that possible?

a的值是100。这怎么可能?

5 个解决方案

#1


16  

I can't even spell c, but I can tell you why.

我甚至不会拼写c,但我可以告诉你为什么。

You have set a to be an int. pow() generates a floating point number, that in SOME cases may be just a hair less than 100 or 10000 (as we see here.)

您已经将a设置为int. pow()生成一个浮点数,在某些情况下,这个浮点数可能仅仅是少于100或10000的一根头发(正如我们在这里看到的)。

Then you stuff that into the integer, which TRUNCATES to an integer. So you lose that fractional part. Oops. If you really needed an integer result, round may be a better way to do that operation.

然后将其填充到整数中,整数截断为整数。所以你失去了小数部分。哦。如果您确实需要一个整数结果,round可能是执行该操作的更好方法。

Be careful even there, as for large enough powers, the error may actually be large enough to still cause a failure, giving you something you don't expect. Remember that floating point numbers only carry so much precision.

即使有足够大的能力,也要小心,错误可能会大到足以导致失败,给你一些你意想不到的东西。记住浮点数只有这么多的精度。

#2


10  

The function pow() returns a double. You're assigning it to variable a, of type int. Doing that doesn't "round off" the floating point value, it truncates it. So pow() is returning something like 99.99999... for 10^2, and then you're just throwing away the .9999... part. Better to say a = round(pow(10, i)).

函数pow()返回一个double。你将它赋值给变量a,类型为int类型,这样做不会“四舍五入”浮点值,它会截断它。所以pow()返回了99。99999…10 ^ 2,然后你只是扔掉.9999……部分。最好说a = round(pow(10, i))。

#3


9  

This is to do with floating point inaccuracy. Although you are passing in ints they are being implicitly converted to a floating point type since the pow function is only defined for floating point parameters.

这与浮点精度有关。尽管您正在传递ints,但它们正在隐式地转换为浮点类型,因为pow函数仅为浮点参数定义。

#4


1  

Mathematically, the integer power of an integer is an integer.

从数学上讲,整数的整数幂是整数。

In a good quality pow() routine this specific calculation should NOT produce any round-off errors. I ran your code on Eclipse/Microsoft C and got the following output:

在一个高质量的pow()例程中,这个特定的计算不应该产生任何舍入错误。我在Eclipse/Microsoft C上运行了您的代码,得到如下输出:

1   10  100 1000    10000   

This test does NOT indicate if Microsoft is using floats and rounding or if they are detecting the type of your numbers and choosing the appropriate method.

这个测试并不表明微软是否在使用浮点数和舍入,或者他们是否在检测你的数字类型并选择合适的方法。

So, I ran the following code:

因此,我运行了以下代码:

#include <stdio.h>#include <math.h>main (){    double i,a;    for(i=0.0; i <= 4.0 ;i++)    {        a=pow(10,i);        printf("%lf\t",a);    }}

And got the following output:

得到如下输出:

1.000000    10.000000   100.000000  1000.000000 10000.000000    

#5


1  

No one spelt out how to actually do it correctly - instead of pow function, just have a variable that tracks the current power:

没有人详细说明如何正确地完成它——除了pow函数,只有一个变量来跟踪当前的功率:

int i, a, power;    for (i = 0, a = 1; i <= 4; i++, a *= 10) {        printf("%d\t",a);    }

This continuing multiplication by ten is guaranteed to give you the correct answer, and quite OK (and much better than pow, even if it were giving the correct results) for tasks like converting decimal strings into integers.

这个10的连续乘法可以保证给出正确的答案,而且对于像将十进制字符串转换成整数这样的任务来说,它比pow好得多(即使它给出了正确的结果)。

#1


16  

I can't even spell c, but I can tell you why.

我甚至不会拼写c,但我可以告诉你为什么。

You have set a to be an int. pow() generates a floating point number, that in SOME cases may be just a hair less than 100 or 10000 (as we see here.)

您已经将a设置为int. pow()生成一个浮点数,在某些情况下,这个浮点数可能仅仅是少于100或10000的一根头发(正如我们在这里看到的)。

Then you stuff that into the integer, which TRUNCATES to an integer. So you lose that fractional part. Oops. If you really needed an integer result, round may be a better way to do that operation.

然后将其填充到整数中,整数截断为整数。所以你失去了小数部分。哦。如果您确实需要一个整数结果,round可能是执行该操作的更好方法。

Be careful even there, as for large enough powers, the error may actually be large enough to still cause a failure, giving you something you don't expect. Remember that floating point numbers only carry so much precision.

即使有足够大的能力,也要小心,错误可能会大到足以导致失败,给你一些你意想不到的东西。记住浮点数只有这么多的精度。

#2


10  

The function pow() returns a double. You're assigning it to variable a, of type int. Doing that doesn't "round off" the floating point value, it truncates it. So pow() is returning something like 99.99999... for 10^2, and then you're just throwing away the .9999... part. Better to say a = round(pow(10, i)).

函数pow()返回一个double。你将它赋值给变量a,类型为int类型,这样做不会“四舍五入”浮点值,它会截断它。所以pow()返回了99。99999…10 ^ 2,然后你只是扔掉.9999……部分。最好说a = round(pow(10, i))。

#3


9  

This is to do with floating point inaccuracy. Although you are passing in ints they are being implicitly converted to a floating point type since the pow function is only defined for floating point parameters.

这与浮点精度有关。尽管您正在传递ints,但它们正在隐式地转换为浮点类型,因为pow函数仅为浮点参数定义。

#4


1  

Mathematically, the integer power of an integer is an integer.

从数学上讲,整数的整数幂是整数。

In a good quality pow() routine this specific calculation should NOT produce any round-off errors. I ran your code on Eclipse/Microsoft C and got the following output:

在一个高质量的pow()例程中,这个特定的计算不应该产生任何舍入错误。我在Eclipse/Microsoft C上运行了您的代码,得到如下输出:

1   10  100 1000    10000   

This test does NOT indicate if Microsoft is using floats and rounding or if they are detecting the type of your numbers and choosing the appropriate method.

这个测试并不表明微软是否在使用浮点数和舍入,或者他们是否在检测你的数字类型并选择合适的方法。

So, I ran the following code:

因此,我运行了以下代码:

#include <stdio.h>#include <math.h>main (){    double i,a;    for(i=0.0; i <= 4.0 ;i++)    {        a=pow(10,i);        printf("%lf\t",a);    }}

And got the following output:

得到如下输出:

1.000000    10.000000   100.000000  1000.000000 10000.000000    

#5


1  

No one spelt out how to actually do it correctly - instead of pow function, just have a variable that tracks the current power:

没有人详细说明如何正确地完成它——除了pow函数,只有一个变量来跟踪当前的功率:

int i, a, power;    for (i = 0, a = 1; i <= 4; i++, a *= 10) {        printf("%d\t",a);    }

This continuing multiplication by ten is guaranteed to give you the correct answer, and quite OK (and much better than pow, even if it were giving the correct results) for tasks like converting decimal strings into integers.

这个10的连续乘法可以保证给出正确的答案,而且对于像将十进制字符串转换成整数这样的任务来说,它比pow好得多(即使它给出了正确的结果)。