代表大数的一般提示


21

有时,打高尔夫球时,需要在其代码中表示大量数字。照原样写入它们可以大大增加字节数。

您在代码中简洁地表示长数字时有哪些一般的1小技巧?

请为每个答案发布一个提示。


1随着一般,我的意思是可以适用于多单的语言技巧。有关特定于语言的提示,请在各自的主题中发布。




我看到有人误解了这个问题-也许标题应该说这是关于打高尔夫球的。
与Orjan约翰森

Answers:


15

留意特殊号码

某些语言具有内置函数,用于平方,以2为底的第n个素数,阶乘或其他可以生成大量数字的过程。检查您的人数是否恰好属于这些类别。

如果不是这样,则可能会出现更多符合您目的的数字,可以代替使用。


4
即使您无法使用内置函数生成所需的数字,也可能生成一个数字,您可以将其用作简单计算的基础,以得出所需的数字,同时仍可以节省字节数来写出该数字。
毛茸茸的

7
+1表示“更大的数字”-如果1.01e6迭代足够,则1e7节省3个字节,但会浪费运行时间。
克里斯·H

13

使用按位布尔运算符

某些语言具有按位与,或,异或,有时没有。

将特定的大数表示为取幂或左移的结果与另一个数字的按位组合,可以使您精确地找到所需的数字。通常只有在数字很大时才值得。

例如,2147483722是10个字节,但是2<<30^74(2 ^ 31按位与74进行XOR)只有8。


3
如果语言具有该运算符(例如bc),则可以将其替换为幂运算。XOR从未比+and 更有用-:在这种情况下,xor和add给出相同的结果,但是在所有情况下,都可以对某些整数进行加或减以产生与带有整数的xor相同的结果,并且加数为没有更大,有时更短。
里奇

3
@rici如果所有整数都写成简单的小数,则为true,但很有可能将xor所使用的整数缩短,而加或减所使用的整数则不能这样做:想像1e9^2e9
hvd

2
@rici您将如何9<<49^7<<19使用加法而不是xor表示?
L3viathan '17

2
@rici不,我的意思是我写的。它1286561280使用JavaScript和Perl(可能还有其他语言)进行求值,与使用+或相比,生成该值的表达式更短-
hvd

@hvd:好的,要点。
rici

11

使用字符串作为重复数字

对于本质上非常重复的数字,可以使用字符串并将其强制转换为整数。例如,在JavaScript中

+"1".repeat(100) // returns 100 1s (saves 84 bytes!)

2
或者,1e100/9在这种情况下,您可以使用很大一部分。
ETHproductions's

11

使用科学计数法

如果数字较长,科学计数法可以节省字节。例如:

3564e-8 // returns 0.00003564 (saves 3 bytes!)

3
为什么不只3564e-8在这种情况下使用?
乔伊,

@Joey是的,当然!谢谢!:)
Arjun

当然,您通常可以将另一个数字写为.00003564,该数字也要再短一个字节。
乔伊(Joey)

@Joey并非每种语言都可以,因此,我不会在其中进行编辑。–
Arjun

3564(左)变成354(右)是故意的还是错字?
艾瑞克(Erik)

10

寻找其他号码代替

这听起来像是没有答案,但并非总是很明显,较短的代码可以计算出更大的数字。我记得一个示例是输出字符串的googol副本,其中明显的答案需要计算10 100。事实证明,计算10 100的任何倍数会得出同样正确的答案,但在某些语言中,答案更短。丹尼斯的答案在那里使用100 100,我自己的使用250 255


4
CJam的另一个示例是CJam,es如果您只需要大量但不关心其值(或者始终相同),则可以获取当前时间戳。
马丁·恩德

10

基本压缩

基本解压缩代码可能非常复杂,但是如果您的数量确实很多,则有时可以将其压缩到大于10的某个基本数量。

在某些语言中,基本压缩代码也非常简单,这也有帮助。例如,PHP具有base64_decode(_),Python具有int(_,36),JavaScript具有parseInt(_,36),并且许多高尔夫球语言都具有基本的解压缩内置函数。例如,在CJam中:

"+ÜTbô±"256b

其中包含不可打印的内容。在线尝试!

这样产生:

12345678987654321

9

对大的重复数使用指数分数

假设您要生成由100 1组成的数字。您可以使用int("1"*100)+"1".repeat(100)等等,但是您也可以利用它非常接近

1e100/9

这对于重复性很高的数字(例如由一个数字组成的数字)最有效。几个重复的数字也可以很好地工作:

12e100/99  // Generates 121212121212... (100 digits)

有时,您会发现其他一些奇怪的模式,这种模式也可以用简洁的方式表示出来。int("123456790"*11)例如,如果您碰巧需要:

1e100/81

但是要小心:数字之类的表示方法int("1234567890"*10)不那么容易。


9

使用按位左移2的幂

尽管有许多语言支持运算符求幂,但有些语言则不支持。而那些不需要的函数通常需要调用函数(或Class / Object方法),这可能会花费几个字节。

但是,当需要将2 乘幂n时,可以使用Bitwise Left Shift运算符<<as 来节省一些字节1<<n。请注意,这只会在n大于或等于17时为您节省字节。但是,如果n是动态的,则将始终为您节省字节。几个例子:

1<<2 // returns 4 (3 bytes more :( )
1<<3 // returns 8 (3 bytes more :( )
1<<6 // returns 64 (2 bytes more :( )
1<<14 // returns 16384 (no bytes saved)
1<<17 // returns 131072 (saves 1 byte!)
1<<18 // returns 262114 (saves 1 byte!)

4
请注意,您可以使用其他值代替1。 8<<9 // 4096因此,我们最多可以得到99<<616个字节,这等于6,917,529,027,641,081,856节省了13个字节!
Draco18s

@ Draco18s是的,这里已经介绍
阿肯(Arjun)

再说一遍布尔的按位运算符。是的,它也具有位移功能,但是它正在谈论使用两个大数进行异或运算,并获得第三个特定数字。
Draco18s '17

7

中国剩余定理

如果频繁出现任意大整数,或者目标编程语言中的大整数表示占用太多字节,则可以考虑使用中文余数定理。

选择一些成对的相对质数m i > = 2,您可以表示从0到lcm(m 1,m 2,...,m i)-1的大数

例如,我选择2、3、5、11、79、83、89、97,那么我可以唯一表示小于18680171730的数字。10000000000(1e10)可以表示为0,1,0,1,38,59,50,49(1e10 mod 2,3 ...,97),而不必表示为可能节省的特殊Big Integer类/结构一些编程语言中的一些字节。

加法和减法可以直接使用此表示法进行。例:

(0,1,0,1,38,59,50,49)+(0,2,0,6,23,20,16,53) = 1e10 + 5000 
                                            = (0+0 mod 2, 1+2 mod 3, 0+0 mod 5, 1+6 mod 11, 38+23 mod 79, 59+20 mod 83, 50+16 mod 89, 49+53 mod 97)

1
想要详细说明吗?
Skidsdev

@Mayube我添加了一些解释,但是我怀疑在大多数情况下它没有用。
咏叹调斧

1
这是“余数定理”。
与Orjan约翰森

6

使用字符串填充(如果可能)

如果较大的数字在开头或结尾都包含重复的数字,则可以使用一种语言的填充方法来构造要查找的数字字符串,从而节省字节,然后将其转换为整数。


1111111111111111111111112在JavaScript(ES8)中生成数字(25个字节):

+"2".padStart(25,1) // 19 bytes

3

使用指数

如果您的语言具有指数运算符,那么您也许可以使用它来生成(如果不是您想要的数字)至少一个可以执行简单计算的数字或2来得出您的数字。即使没有操作员,您仍然可以使用内置函数或方法保存字节。

JavaScript中最大安全整数9007199254740991,长度为16位。在ES7中,可以使用以下7个字节来计算:

2**53-1

与ES6及更早版本中的等效项相同,但在这种情况下,其长度与整数本身相同,这表明使用更详细的方法不一定会花费您任何字节。

Math.pow(2,53)-1

但是,例如,如果您已经在代码的其他位置将别名别名为单个字符,则上述内容可能会更短一些Math


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.