wrong output by power function - C
pow()函数给出了非常奇怪的输出。
我尝试了各种组合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include<stdio.h>
#include<math.h>
int main()
{
int d=1;
long long n1,n2;
while(d<10)
{
n1=pow(10,d);
n2=pow(10,d);
d++;
printf("%lld %lld\
",n1,n2);
}
} |
这样会产生错误的输出,即99,而不是100,如此。
现在,如果我删除变量之一,ans。 是正确的。
如果不是d,我使用一个常数,ans是正确的。
如果我将n1和n2设为两倍,ans是正确的。
因此,拥有两个pow()函数同时具有变量的幂和类型强制转换为整数的pow()函数会产生不良输出。
为什么这种奇怪的行为?
-
欢迎使用IEEE 754。
-
实现您的pow。
-
如果您想要确切的答案,可以考虑制作自己的求幂算法
-
@MarounMaroun不是重复的。 我的问题是使用一个pow很好,如果有两个pow,我们在第二个pow()中得到错误的输出
这是从浮点值(将小数点舍入而不是四舍五入)制成整数的情况,以及pow(x, y)转换为exp(log(x) * y)的事实,这将产生与精确度不同的结果 as xy-几乎是一个近似的浮点值,例如102的99.9999996(或100.00002)。
如果要四舍五入,请使用round(pow(x, y))。
-
但是那应该是一个一致的问题..不是吗?如果我在代码中仅使用一个pow(),那么即使我将其转换为整数,答案也将是正确的。一个pow()如何影响另一个?
-
编译器会进行各种优化。如果您仅对pow进行一次调用,则可以很好地决定它可以通过每次简单地乘以10来优化它。在您有两次调用pow的情况下,它决定实际调用pow,因为它占用了太多的代码空间来进行计算或类似的操作。
-
谢谢Mats!我完全不知道编译器所做的任何此类优化。
-
pow(x, y)不会"翻译为" exp(log(x) * y)多于x*y转化为exp(log(x) + log(y))。
-
@EricPostpischil:不,它的计算要复杂得多。在i386上,它区分y的整数值并执行循环。但是在y不是整数的情况下,它会执行2^fract(y*log2(x))*2^int(y*log2(x))-完全不像我写的那样,但是在我的书中已经足够接近了。我非常确定该标准没有说明应如何实施。但是,如果OPs函数对pow执行操作实际上是执行整数步循环[如果当前y的值是偶数,它也会进行优化并执行x*x,但这不应该改变事情],它如何得出一个99值?
-
@MatsPetersson:写"它确实2^fract(y*log2(x))*2^int(y*log2(x))"和" [该标准并没有说明应如何实施"这两者似乎是矛盾的。只有后者是正确的。 pow的计算比我在评论中所写的要复杂得多。假设pow使用整数步的循环的问题是必然的。我没有提出这种可能性。
-
该公式来自glibc-支持我的说法,即它是exp(log(x) * y)类型计算的一种形式。当然,每个C库都有权以他们喜欢的任何方式实现此目的(这会产生足够准确的结果)。如果不写完整的文章来计算pow()的可能方法,您将如何解释它的作用-显然不可能简单地实现为循环[尽管,glibc同样会检测"整数y"并执行必要的计算使用循环]。也许我应该说"计算是神奇的,使用浮点数"。
当对变量使用pow时,其结果为double。 分配给int会将其截断,您将得到99而不是99.9999999。
编译器会优化使用不带变量的pow(这是在编译时计算的)。
-
但是pow()之一给出正确的ans。即使有变量仅在代码中有两个pow()函数的情况下,第二个pow()给出了错误的ans