大数的数学表示?

时间:2012-04-23 04:08:49

标签: algorithm math

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

简单数学,我的意思是数字 +, - ,*,/,^ ()

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

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

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

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

4 个答案:

答案 0 :(得分:2)

我认为整个问题可以重新解释为长整数二进制表示的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个,其次是500个零。这表明了一个表达式:

2**1024 - 2**512

这是我首先获得大数字的方式。

如果整数的二进制表示中没有显着长的运行,则根本不能正常运行。 101010101010101010....是最糟糕的情况。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我建议你看看

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

  2. 看看integer factorization。该链接重定向到维基百科,这可能会给出一个很好的概述。但要更加科学:

答案 3 :(得分:0)

这是我在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)),因此非常有效。