pow() 似乎在这里少了一个 [英] pow() seems to be out by one here

查看:23
本文介绍了pow() 似乎在这里少了一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里发生了什么:

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆