【问题标题】:How to efficiently calculate the numbers in a range of digits for an exponential function如何有效地计算指数函数的数字范围内的数字
【发布时间】:2020-07-09 03:19:06
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

  • 您能否展示您已经编写的程序,并解释您的程序究竟是如何不工作或没有产生预期的结果?你必须先展示你的作品;它必须满足minimal reproducible example 的所有要求;在通过 stackoverflow.com 寻求帮助之前,它必须是真诚的真正尝试来实现您的程序,而不是几行象征性的代码。我们不会在这里为其他人编写整个程序。有关更多信息,请参阅How to Ask 问题、获取tour 并阅读help center
  • 不是真正的编程问题。也许问数学。另请参阅 en.wikipedia.org/wiki/… 了解想法。
  • @SamVarshavchik:这个问题已经充分说明了。最小可重现示例主要用于寻求调试帮助的问题,而这不是这样的问题。请不要对问题应用不适当的标准。
  • pow (0.123, 100) 有什么问题?不仅仅是一个修辞问题;如果您回答了这个问题,那么我们就会更好地了解您的实际需求。
  • @SamVarshavchik:字数与您的评论是否恰当无关。说问题“必须”满足最小可重现示例的所有要求是错误的。没有什么可重现的,因为问题不是寻求现有程序的帮助。它征求意见。那是在堆栈溢出的范围内;有些问题是关于理论或方法的,而不是调试或构建特定程序。就是这样,没有理由应该提供一个最小的可重现示例。

标签: c++ c math computer-science


【解决方案1】:

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

如果您对有理数f 的小数位d 感兴趣,您可以计算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个十进制数字。并且必要的有效位数使 双精度数据类型 无用。出于这个原因,对大整数的计算是一个合理的实际折衷方案。

【讨论】:

  • 抱歉语法高亮错误。 // 是 Python 中的有效运算符,而不是注释分隔符。
  • 我修复了语法高亮。 OP 在问题中说使用高精度库需要太多时间,这对于有理数库也是一样的。他们在问是否有不需要计算整数的捷径,因此可能更快。
  • @walnut 由于计算时第n个小数位受到所有低位数字的影响,所以没有转义,不能直接计算选中的小数位。我想证明没有必要使用浮点数,大整数就足够了。事实上,我使用有理数只是为了简洁,实现可以简化为整数。
  • 对我来说,计算整个小数扩展(或精确的分子/分母)必须与计算小数扩展的一部分一样昂贵,这对我来说并不明显。但如果这是你的观点,我认为你应该在答案中说清楚。这个问题本身似乎是一个相当重要的数学问题。
  • @walnut OP 的示例 0.123^100 有 209 个有效数字,最高有效数字位于小数点后第 92 位。 OP 对小数位 101、102 等感兴趣,因此无论如何都必须计算几乎整个结果。这绝对是一个有趣的数学问题。
猜你喜欢
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 2013-02-15
  • 2018-03-19
  • 2021-07-02
  • 1970-01-01
  • 2018-08-06
相关资源
最近更新 更多