【问题标题】:Comparing large powers in Ruby using Mod 10使用 Mod 10 比较 Ruby 中的强大功能
【发布时间】:2015-08-03 16:46:36
【问题描述】:

我正在尝试编写一个函数来比较一个数字 x1 与另一个数字 x2 的幂是否大于另一个数字 y1 与另一个数字 y2 的幂。

例如,假设我们有一对 x 的数字。

x = [2,10]

还有一对y

y = [3,9]

在这种情况下,y1 ** y2 大于 x1 ** x2

但是,有时会有非常大的、可怕的数字。像这样

x = [935243113, 987702643]
y = [50894069, 704259526]

为了计算这个,我尝试使用 mod 10 算法

(x[0] ** x[1]) % 10 > (y[0] ** y[1]) % 10 

但是,显然这种算法不起作用。有没有更有效的算法。

【问题讨论】:

  • 这在理论上可行吗?我不明白为什么比较 mod10 结果应该说明完整结果的顺序。反例:10**10 vs 9**9
  • 我通过 Stack Overflow 找到了该算法。它可能应该
  • 好吧,让我更难地反驳它:考虑一个包含 10 多个不同幂的列表,最多有 10 个模 10 的不同结果,因此其中至少有两个得到相同的结果并将比较“相等”(不大于另一个),即使我们只是假设它们是不同的。
  • (x[0] ** x[1]) % 10 还是算x[0] ** x[1]

标签: ruby algorithm numbers modulus largenumber


【解决方案1】:

对任意和取模 10 并比较它们与取随机数没有太大区别。你无法避免这里的数字规模。模可能有助于确定两个数是否相等(如果总和对任何数的模不相等,您可以假设它们不相等)。另请注意,Ruby 仍会在您的情况下计算大数 - 但如果您在模算术中更详细地进行取幂运算,您可以使用一些技巧来避免这种情况。

对于一个应该几乎一直有效的近似方法,那么您可以使用 Math.log( x ** y ) == y * Math.log( x ) 的事实。

像这样:

(Math.log(x[0]) * x[1]) > (Math.log(y[0]) * y[1])

当我说几乎时,我的意思是您在这里暴露了浮点不准确性。由于Math.log 中的舍入,两个非常大但非常相似的指数可能会以错误的顺序出现。我不确定您所显示的数字是否存在实际问题。

更新:

2 ** 9 == 8 ** 3
# => true

但是

(Math.log(2) * 9) > (Math.log(8) * 3)
# => true

因此,完全相等的值的舍入错误是一个更严重的问题,并且可能会在输入数字非常低的情况下发生。如果两个输入可能相等并且知道值是否严格不同很重要,那么当日志/日志比较的结果非常接近时,您需要回退到不同的机制,例如两个对数和之比在 1.0 的 1e-6 以内。

【讨论】:

    猜你喜欢
    • 2013-02-26
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 2013-10-03
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多