c++ - 如何有效地计算指数函数的数字范围内的数字
问题描述
我有一个指数函数 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中的任何数字。这就是为什么一个高精度的库在这里可能不合适,因为它会做很多不必要的计算。
解决方案
您需要一个用于计算大整数的库。您可以使用此库和相应的计算来实现有理数。然后很容易获得有理数的任何十进制数字。查看 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 个十进制数字。并且必要的有效位数使双精度数据类型无用。出于这个原因,对大整数的计算是一个合理的实际折衷方案。
推荐阅读
- java - Solr 中的查询提升组件在 Lucene 中是如何实现的?
- python - 在 cpp 中使用 boost python 的 python 代码是否进行动态内存分配?
- arrays - 错误使用尺寸输入必须是整数?
- python - pyarrow.parquet.write_to_dataset() 使用 partition_cols 时速度极慢
- c++ - 使用 std::tie 进行类似 golang 的错误处理同时返回结果是否有缺点?(C++11)
- c# - 定时器结合 Application.DoEvents 不工作
- reactjs - 对点击放置图像做出反应
- visual-studio - 新项目列表未填充 v2 (.NET Core)
- node.js - 使用 Google Functions & Node JS 10 复制整个源文件夹而不仅仅是触发器文件
- c# - 如何使 checkBoxList 项目只读或将其删除?