Algorithm 大数的数学表示法?
我正在尝试编写一个函数,它以一个大的数字作为输入(长度超过800位),并以字符串的形式返回一个简单的公式 通过简单的数学,我的意思是根据需要使用+,-,*,/,^和()的数字Algorithm 大数的数学表示法?,algorithm,math,Algorithm,Math,我正在尝试编写一个函数,它以一个大的数字作为输入(长度超过800位),并以字符串的形式返回一个简单的公式 通过简单的数学,我的意思是根据需要使用+,-,*,/,^和()的数字 '4^25+2^32'=giveMeMath(1125904201809920);//示例 任何语言都可以。我可以重构它,只是想在逻辑上寻求一些帮助 奖金。输出越短越好。处理时间很重要。此外,数学准确性是必须的 更新: 为了澄清,在java中,所有输入值都将是正整数(无小数),您应该看看java.math包中的BigDec
'4^25+2^32'=giveMeMath(1125904201809920);//示例
任何语言都可以。我可以重构它,只是想在逻辑上寻求一些帮助
奖金。输出越短越好。处理时间很重要。此外,数学准确性是必须的
更新:
为了澄清,在java中,所有输入值都将是正整数(无小数),您应该看看java.math包中的
BigDecimal
类。我建议您看看
- (PDF)由伊利诺伊大学
- (PDF)俄勒冈州州立大学物理系的康奈利·巴恩斯
以下是我在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(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)
但是输出太长了,不能在这里发布,这当然是OPs关注的问题
这里的时间复杂度是0(ln(n)),因此它非常有效。我认为整个问题可以重新表述为一个关于长整数的二进制表示的问题 例如,以以下数字为例:
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….是最坏的情况。是否有一些标准需要公式使用?有很多表达式将计算为给定的数字。Lisp非常适合处理大数字。如果你想要一个“优雅”的数字表示法,你可以使用不同的复杂算法计算出一系列不同的表示法,然后选择最短的表示法。你的问题听起来类似于压缩大量的位。我将研究常见的压缩算法是如何工作的。您是否打算缩短数字表示的长度?@conductr,您将无法实现对任意数字的压缩。乘法和加法不会给你任何只压缩的指数,你只能对一小部分数字应用它。谢谢你的推荐。你是说有一个内置方法已经完成了我需要的功能吗?BigDecimal有很多你需要的操作,但你必须编写一个解析器来将你的语言映射到这些方法。我想我误解了你的问题,我可以说的一件事是,我不认为你的源代码中有那么大的文字,除非是字符串文字,否则结果是准确的。另一方面,如果你想要的函数随机抽取你的数字的因子,那么这是一种奇怪的行为。它是关于大数字的(100位是语句),所以我认为这不会起作用。@akavall这是一个很好的开始,我可以加进去,当然,下一步是增加基数,这将减少输出。@conductr是的,我认为下一步是使用不同的基数组合来减少输出。我用这个二进制方法做了一些简单的研究,这也是我在实践中不断遇到的问题(使用随机数)长时间运行是非常罕见的,以至于这变得不切实际。根据定义,随机数是不可压缩的。一个
n
位的随机数包含大约n
位的熵-你不能再压缩它了。
2**1024 - 2**512