pow() 似乎在这里少了一个 [英] pow() seems to be out by one here
问题描述
这里发生了什么:
#include <stdio.h>
#include <math.h>
int main(void) {
printf("17^12 = %lf
", pow(17, 12));
printf("17^13 = %lf
", pow(17, 13));
printf("17^14 = %lf
", pow(17, 14));
}
我得到这个输出:
17^12 = 582622237229761.000000
17^13 = 9904578032905936.000000
17^14 = 168377826559400928.000000
13 和 14 与 不匹配wolfram alpa cf:
13 and 14 do not match with wolfram alpa cf:
12: 582622237229761.000000
582622237229761
13: 9904578032905936.000000
9904578032905937
14: 168377826559400928.000000
168377826559400929
此外,某个奇怪的分数并没有错 - 正好是一个!
Moreover, it's not wrong by some strange fraction - it's wrong by exactly one!
如果这取决于我达到了 pow()
可以为我做什么的极限,是否有替代方法可以计算这个?我需要一个可以计算 x^y
的函数,其中 x^y
总是小于 ULLONG_MAX.
If this is down to me reaching the limits of what pow()
can do for me, is there an alternative that can calculate this? I need a function that can calculate x^y
, where x^y
is always less than ULLONG_MAX.
推荐答案
pow
适用于 double
数字.这些表示 s * 2^e 形式的数字,其中 s 是 53 位整数.因此 double
可以存储所有小于 2^53 的整数,但只能存储 一些 大于 2^53 的整数.特别是,它只能表示 > 2^53 的偶数,因为对于 e > 0,该值始终是 2 的倍数.
pow
works with double
numbers. These represent numbers of the form s * 2^e where s is a 53 bit integer. Therefore double
can store all integers below 2^53, but only some integers above 2^53. In particular, it can only represent even numbers > 2^53, since for e > 0 the value is always a multiple of 2.
17^13 需要 54 位来精确表示,因此 e 设置为 1,因此计算的值变为偶数.正确的值是奇数,因此相差 1 也就不足为奇了.同样,17^14 需要 58 位来表示.它也差一个是一个幸运的巧合(只要你不应用太多的数论),它恰好是一个 32 的倍数,这是粒度double
数值在该数值处四舍五入.
17^13 needs 54 bits to represent exactly, so e is set to 1 and hence the calculated value becomes even number. The correct value is odd, so it's not surprising it's off by one. Likewise, 17^14 takes 58 bits to represent. That it too is off by one is a lucky coincidence (as long as you don't apply too much number theory), it just happens to be one off from a multiple of 32, which is the granularity at which double
numbers of that magnitude are rounded.
对于精确的整数求幂,您应该一直使用整数.编写您自己的 double
-free 求幂例程.如果 y
可以很大,则使用平方取幂,但我假设它总是小于 64,这使得这个问题没有实际意义.
For exact integer exponentiation, you should use integers all the way. Write your own double
-free exponentiation routine. Use exponentiation by squaring if y
can be large, but I assume it's always less than 64, making this issue moot.
这篇关于pow() 似乎在这里少了一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!