首页 > 解决方案 > 如何有效地计算指数函数的数字范围内的数字

问题描述

我有一个指数函数 x^n,其中 x 是 0-1 之间的数字,n 是一个大整数(通常 > 100)。假设用双精度数表示时 x 和 n 没有舍入误差。如何有效地计算 x^n 的数字范围内的数字?例如,我只想获取 0.123^1000 的小数点后两千位的数字。

我知道像 MPFR 这样的高精度库可以完美地完成这项工作,但它比双精度计算慢得多。由于我不需要数字中的所有数字,因此我正在寻找一种更有效的方法来做到这一点,但我对此一无所知。任何建议或提示将不胜感激。

====================update1====================

感谢大家的评论和回答,我注意到问题中的示例可能不合适,因为数字仍然不足以导致截断,因此我将其更改为 0.123^1000。

对于那些喜欢看一些真实代码的人,我在 R 中做了一个可重现的例子

x <- 0.123^1000
sprintf("%.10e",x)
y <- mpfr(0.123,precBits = 10000)^1000
y

x 是双精度数,结果为 0,y 是 10000 位精度数,实际上可以显示第 2001 位十进制数的结果数。请注意,前几个(可能很多)有效数字通常不感兴趣,也就是说,如果指数函数的真实答案是 0.123 + 4 * 10^10000,我会对那个“4”感兴趣,而不是1,2,3中的任何数字。这就是为什么一个高精度的库在这里可能不合适,因为它会做很多不必要的计算。

标签: c++cmathcomputer-science

解决方案


您需要一个用于计算大整数的库。您可以使用此库和相应的计算来实现有理数。然后很容易获得有理数的任何十进制数字。查看 Python 中的代码示例。

d如果您对有理数的小数位感兴趣f,您可以计算f * 10^d,只使用它的整数部分并且只取最低有效位。

import fractions

def get_digit(f, d):
    f1 = f * 10**d
    return (f1.numerator // f1.denominator) % 10

f = fractions.Fraction(123, 1000)
p = f ** 100

assert get_digit(p, 91) == 0
assert get_digit(p, 92) == 9
assert get_digit(p, 93) == 7
assert get_digit(p, 94) == 8
assert get_digit(p, 95) == 3
assert get_digit(p, 96) == 8

更新:

在计算期间,第 n 个十进制数字受所有低有效十进制数字的影响。因此,不可能直接计算第 n 个十进制数字。并且必要的有效位数使双精度数据类型无用。出于这个原因,对大整数的计算是一个合理的实际折衷方案。


推荐阅读