【问题标题】:Mathematical representation of large numbers?大数的数学表示?
【发布时间】:2012-04-23 04:08:48
【问题描述】:

我正在尝试编写一个函数,该函数将大量数字作为输入(长度超过 800 位)并返回一个简单的不复杂数学公式作为字符串。

通过简单的数学,我的意思是数字,根据需要带有 +,-,*,/,^()。 p>

'4^25+2^32' = giveMeMath(1125904201809920); // example

任何语言都可以。我可以重构它,只是在逻辑上寻求一些帮助。

奖金。输出越短越好。处理时间很重要。此外,数学准确性是必须的。

更新: 澄清一下,所有输入值都是正整数(没有小数)

【问题讨论】:

  • 您需要使用公式吗?有无数个表达式可以计算为给定的数字。
  • Lisp 非常适合处理大量数字。如果您想要一个数字的“优雅”表示,您可以使用单独的复杂算法计算一堆不同的表示,然后选择最短的一个。
  • 您的问题听起来类似于压缩大量位。我会研究常见的压缩算法是如何工作的。
  • 您是否打算能够缩短数字表示的长度?
  • @conductr,您将无法实现任意数字的压缩。乘法和加法不会给你任何压缩 - 只有指数,你只能将其应用于相对较小的数字。

标签: algorithm math


【解决方案1】:

我认为整个问题可以重铸为关于长整数二进制表示的run-length encoding 问题。

例如,取下面的数字:

17976931348623159077293051907890247336179769789423065727343008115773
26758055009631327084773224075360211201138798713933576587897688144166
22492847430639474110969959963482268385702277221395399966640087262359
69162804527670696057843280792693630866652907025992282065272811175389
6392184596904358265409895975218053120L

这看起来相当可怕。但是,在二进制中:

>>> bin(_)
'0b11111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111100000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
0000000'

大约有 500 个 1,然后是 500 个 0。这暗示了这样的表达:

2**1024 - 2**512

我最初是如何获得大量的。

如果在整数的二进制表示中没有明显的长时间运行,这根本不会很好地工作。 101010101010101010.... 是最坏的情况。

【讨论】:

  • 我用这种二进制方法做了一些简短的挖掘,这也是我一直遇到的问题,实际上(使用随机数)长时间运行非常罕见,这变得不切实际
  • 根据定义,任意随机数是不可压缩的。一个n-bit 随机数包含大约n 位熵 - 你不能进一步压缩它。
【解决方案2】:

这是我在 Python 中的尝试:

def give_me_math(n): 

    if n % 2 == 1:
        n = n - 1  # we need to make every odd number even, and add back one later
        odd = 1
    else:
        odd = 0
    exps = []

    while n > 0:
        c = 0
        num = 0
        while num <= n/2:
            c += 1
            num = 2**c

        exps.append(c)    
        n = n - num
    return (exps, odd)

结果:

>>> give_me_math(100)
([6, 5, 2], 0)  #2**6 + 2**5 + 2**2 + 0 = 100

>>> give_me_math(99)
([6, 5, 1], 1)  #2**6 + 2**5 + 2**1 + 1 = 99

>>> give_me_math(103) 
([6, 5, 2, 1], 1) #2**6 + 2**5 + 2**2 + 2**1 + 1 = 103

我相信结果是准确的,但我不确定您的其他标准。

编辑:

结果:大约一秒钟内计算完毕。

>>> give_me_math(10**100 + 3435)
([332, 329, 326, 323, 320, 319, 317, 315, 314, 312, 309, 306, 304, 303, 300, 298, 295, 294, 289, 288, 286, 285, 284, 283, 282, 279, 278, 277, 275, 273, 272, 267, 265, 264, 261, 258, 257, 256, 255, 250, 247, 246, 242, 239, 238, 235, 234, 233, 227, 225, 224, 223, 222, 221, 220, 217, 216, 215, 211, 209, 207, 206, 203, 202, 201, 198, 191, 187, 186, 185, 181, 176, 172, 171, 169, 166, 165, 164, 163, 162, 159, 157, 155, 153, 151, 149, 148, 145, 142, 137, 136, 131, 127, 125, 123, 117, 115, 114, 113, 111, 107, 106, 105, 104, 100, 11, 10, 8, 6, 5, 3, 1], 1)

800 位也很快:

>>> give_me_math(10**800 + 3452)

但输出太长,无法在此处发布,这当然是 OP 关心的问题。

这里的时间复杂度是0(ln(n)),所以效率很高。

【讨论】:

  • 这是关于大数字的(声明为 100 位),所以我认为这行不通。
  • @akavall 这是一个很好的开始,我可以添加,下一步肯定是增加基数,这将减少输出。
  • @conductr 是的,我认为下一步是使用不同的碱基组合来缩小输出。
【解决方案3】:

在java中,你应该看看java.math包中的BigDecimal类。

【讨论】:

  • 感谢您的推荐。你是说有一个内置方法已经可以满足我的需要了吗?
  • BigDecimal 有很多您要求的操作,但您必须编写一个解析器来将您的语言映射到这些方法。
  • 我想我误解了你的问题,我可以说的一件事是我不认为你的源代码可以有这么大的文字并期望结果是准确的,除非是字符串文字。另一方面,如果您想要的函数类型随机提取您的数字的因素,那么这是一种奇怪的行为。
【解决方案4】:

建议你看看

  1. 用于执行算术运算的 GMP 库(GNU 多精度算术库)

  2. 看看integer factorization。该链接重定向到维基百科,这应该可以提供一个很好的概述。不过要科学一点:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-15
    • 1970-01-01
    • 2014-02-13
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    相关资源
    最近更新 更多