Allgemeine Tipps zur Darstellung großer Zahlen

21

Manchmal muss man beim Golfen eine große Zahl (en) in seinem Code darstellen. Wenn Sie sie so schreiben, wie sie sind, kann sich die Anzahl der Bytes erheblich erhöhen.

Welche allgemeinen 1 Tipps haben Sie für die übersichtliche Darstellung langer Zahlen im Code?

Bitte posten Sie einen Tipp pro Antwort.


1 Mit allgemeinen , ich meine Tipps , die eine einzige Sprache auf mehr als angewendet werden kann. Für sprachspezifische Tipps posten Sie in ihrem jeweiligen Thread.

Arjun
quelle
Verbunden.
Martin Ender
Ich habe jemanden gesehen, der die Frage missverstanden hat - vielleicht sollte der Titel sagen, dass es um Golf geht.
Ørjan Johansen
Also also related
Beta Decay

Antworten:

15

Achten Sie auf spezielle Nummern

Einige Sprachen verfügen über integrierte Funktionen für Quadrate, Exponentiation mit Basis 2, n- te Primzahl, Fakultät oder andere Prozeduren, die große Zahlen erzeugen können. Überprüfen Sie, ob Ihre Nummer in eine dieser Kategorien fällt .

Andernfalls kann es vorkommen, dass eine größere Anzahl für Ihre Zwecke geeignet ist und stattdessen verwendet werden kann.

Luis Mendo
quelle
4
Auch wenn die von Ihnen gewünschte Zahl nicht mit einer integrierten Funktion generiert werden kann, kann es möglich sein, eine Zahl zu generieren, die Sie als Grundlage für eine einfache Berechnung verwenden können, um Ihre Zahl zu ermitteln, während Sie beim Ausschreiben immer noch Bytes einsparen.
Shaggy
7
+1 für "größere Anzahl" - Wenn 1.01e6Iterationen ausreichen, werden 1e73 Byte auf Kosten der Laufzeit eingespart.
Chris H
13

Verwenden Sie bitweise Boolesche Operatoren

Einige Sprachen haben bitweise AND, OR, XOR und manchmal NOT.

Wenn Sie eine bestimmte große Zahl als bitweise Kombination aus einem Exponentierungsergebnis oder einer Linksverschiebung und einer anderen Zahl ausdrücken, können Sie genau die Zahl finden, die Sie benötigen. Dies lohnt sich normalerweise nur, wenn die Zahlen ziemlich groß werden.

Zum Beispiel 2147483722ist 10 Bytes, aber 2<<30^74(2 ^ 31 bitweises XOR mit 74) ist nur 8.

L3viathan
quelle
3
Der Schichtoperator kann durch Potenzierung ersetzt werden, wenn die Sprache diesen Operator hat (z bc. B. ). Und XOR ist niemals nützlicher als +und -: In diesem Fall liefern xor und add dasselbe Ergebnis, aber in allen Fällen gibt es eine ganze Zahl, die addiert oder subtrahiert werden kann, um dasselbe Ergebnis wie xor mit einer ganzen Zahl zu erzielen, und die Addition ist nicht größer und manchmal kürzer.
rici
3
@rici Stimmt, wenn alle Ganzzahlen als einfache Dezimalzahlen geschrieben sind, aber es ist möglich, dass die mit xor zu verwendende Ganzzahl auf eine Weise verkürzt werden kann, die die mit plus oder minus zu verwendende Ganzzahl nicht kann: Denken Sie an etwas Ähnliches 1e9^2e9.
HDV
2
@rici Wie würden Sie 9<<49^7<<19Addition anstelle von xor ausdrücken ?
L3viathan
2
@rici Nein, ich meinte was ich schrieb. Es wird 1286561280in JavaScript und Perl (und wahrscheinlich in anderen Sprachen) ausgewertet , und es ist ein kürzerer Ausdruck, um diesen Wert als den entsprechenden mit +oder zu erzeugen -.
HDV
@hvd: OK, Punkt genommen.
rici
11

Verwenden Sie Strings für sich wiederholende Nummern

Bei Zahlen, die sich in der Natur sehr wiederholen, können Sie Strings verwenden und in Integer umwandeln. Zum Beispiel in JavaScript

+"1".repeat(100) // returns 100 1s (saves 84 bytes!)
Arjun
quelle
2
Oder Sie könnten 1e100/9in diesem Fall einen sehr großen Bruch verwenden .
ETHproductions
11

Verwenden Sie die wissenschaftliche Notation

In der wissenschaftlichen Notation können bei langen Zahlen Bytes gespart werden. Beispielsweise:

3564e-8 // returns 0.00003564 (saves 3 bytes!)
Arjun
quelle
3
Warum nicht einfach 3564e-8in diesem Fall verwenden?
Joey
@Joey Ja natürlich! Vielen Dank! :)
Arjun
Zugegeben, man kann in der Regel die andere Zahl als schreiben .00003564, die auch wieder ein Byte kürzer ist.
Joey
@ Joey Nicht jede Sprache, daher werde ich das nicht bearbeiten.
Arjun
Ist es beabsichtigt, dass aus 3564 (links) 354 (rechts) wird, oder ist das ein Tippfehler?
Erik
10

Suchen Sie stattdessen nach einer anderen Nummer

Dies mag nach einer Nichtantwort klingen, aber es ist nicht immer offensichtlich, dass eine größere Zahl durch kürzeren Code berechnet werden kann. Ein Beispiel, an das ich mich erinnere, ist die Ausgabe einer Googol-Kopie eines Strings , bei der die offensichtlichen Antworten die Berechnung von 10 100 erfordern . Wie sich herausstellt, führt die Berechnung eines Vielfachen von 10 100 zu einer ebenso korrekten, aber in einigen Sprachen kürzeren Antwort. Dennis 'Antwort dort verwendet 100 100 , meine eigene 250 255 .

hvd
quelle
4
Ein weiteres Beispiel hierfür ist CJam, mit dem Sie den aktuellen Zeitstempel abrufen können, eswenn Sie nur eine große Zahl benötigen, sich aber nicht um deren Wert kümmern (oder dass er immer derselbe ist).
Martin Ender
10

Basiskomprimierung

Basis-Dekomprimierungscode kann ziemlich komplex sein, aber wenn Sie eine wirklich enorme Anzahl haben, kann es manchmal hilfreich sein, ihn in einer Basis höher als 10 zu komprimieren.

Es hilft auch, dass in einigen Sprachen der Basiskomprimierungscode sehr einfach ist. Zum Beispiel hat PHP base64_decode(_), Python int(_,36), JavaScript parseInt(_,36)und viele Golf-Sprachen haben eine integrierte Basis-Dekomprimierung. Zum Beispiel in CJam:

"+ÜTbô±"256b

Dies enthält eine nicht druckbare. Probieren Sie es online!

Dies ergibt:

12345678987654321
Esolanging Fruit
quelle
9

Verwenden Sie exponentielle Brüche für große sich wiederholende Zahlen

Angenommen, Sie wollten die Zahl aus 100 Einsen generieren. Sie könnten verwenden int("1"*100), +"1".repeat(100)etc. , aber Sie können auch die Vorteile aus der Tatsache ziehen , dass es ganz in der Nähe

1e100/9

Dies funktioniert am besten bei sich sehr wiederholenden Zahlen, z. B. solchen, die aus einer einzelnen Ziffer bestehen. Ein paar wiederholte Ziffern funktionieren auch ziemlich gut:

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

Gelegentlich finden Sie ein anderes seltsames Muster, das auch in dieser Methode ziemlich knapp dargestellt werden kann. Wenn Sie int("123456790"*11)zum Beispiel zufällig brauchen :

1e100/81

Seien Sie jedoch vorsichtig: Zahlen wie int("1234567890"*10)haben keine so einfache Darstellung.

ETHproductions
quelle
9

Verwenden Sie die bitweise Linksverschiebung für die Potenzierung von 2

Es gibt zwar viele Sprachen, die den Operator Exponentiation unterstützen, einige jedoch nicht. Und diejenigen, die dies nicht tun, erfordern normalerweise aufrufende Funktionen (oder Klassen- / Objektmethoden), die einige Bytes kosten können.

Sie können jedoch einige Bytes einsparen, wenn Sie 2 mit dem Operator Bitwise Left Shift as zur Potenz n erhöhen müssen . Beachten Sie, dass Sie dadurch nur Bytes sparen, wenn n größer oder gleich 17 ist. Dies spart jedoch immer Bytes, wenn n dynamisch ist. Einige Beispiele:<<1<<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!)
Arjun
quelle
4
Beachten Sie, dass Sie anstelle von 1 auch andere Werte verwenden 8<<9 // 4096können, sodass wir bis zu 99<<616 Bytes erreichen können, was einer 6,917,529,027,641,081,856Einsparung von 13 Bytes entspricht!
Draco18s
@ Draco18s Ja, und es wird hier behandelt .
Arjun
Dieser deckt die booleschen bitweisen Operatoren ab. Ja, es hat auch die Bitverschiebung, aber es geht darum, zwei große Zahlen für XOR zu verwenden und eine dritte, spezifische Zahl zu erhalten.
Draco18s
7

Chinesischer Restsatz

Wenn häufig beliebige große Ganzzahlen auftreten oder die Darstellung großer Ganzzahlen in der Zielprogrammiersprache zu viele Bytes kostet, können Sie den chinesischen Restsatz in Betracht ziehen.

Wählen Sie paarweise relativ Primzahlen m i > = 2, und Sie können eine große Zahl von 0 bis 1 cm (m 1 , m 2 , ..., m i ) -1 ausdrücken

Zum Beispiel wähle ich 2, 3, 5, 11, 79, 83, 89, 97, dann kann ich eine Zahl kleiner als 18680171730 eindeutig ausdrücken. 10000000000 (1e10) kann ausgedrückt werden als 0,1,0,1,38,59,50,49 (1e10 mod 2, 3 ..., 97), die nicht als spezielle Big Integer-Klasse / Struktur ausgedrückt werden müssen, die möglicherweise speichern Einige Bytes in einigen Programmiersprachen.

Addition und Subtraktion können direkt mit dieser Darstellung erfolgen. Beispiel:

(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)
Aria Axe
quelle
1
Möchten Sie das näher erläutern?
Skidsdev
@ Mayube Ich habe eine Erklärung hinzugefügt, aber ich bezweifle, dass es in den meisten Fällen nutzlos ist.
Aria Axe
1
Es ist "Restsatz".
Ørjan Johansen
6

Verwenden Sie String Padding (wo möglich)

Wenn eine große Zahl eine sich wiederholende Ziffer am Anfang oder Ende enthält, können Sie möglicherweise Bytes speichern, indem Sie eine der Auffüllmethoden Ihrer Sprache verwenden, um eine Zeichenfolge der gesuchten Zahl zu erstellen, die Sie dann in eine umwandeln können ganze Zahl.


Beispiel

So generieren Sie die Anzahl 1111111111111111111111112(25 Byte) in JavaScript (ES8):

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

Verwenden Sie Exponenten

Wenn Ihre Sprache einen Exponentenoperator hat, können Sie ihn möglicherweise verwenden, um die gewünschte Zahl zu generieren, oder um eine einfache Berechnung durchzuführen. Auch ohne Operator können Sie möglicherweise weiterhin Bytes mit einer integrierten Funktion oder Methode speichern.

Beispiel

Der maximale sichere ganze Zahl in JavaScript ist 9007199254740991, die lange 16 - stellig ist. In ES7 kann dies mit den folgenden 7 Bytes berechnet werden:

2**53-1

Das Äquivalent in ES6 und früheren Versionen, obwohl es in diesem Fall dieselbe Länge wie die Ganzzahl selbst hat, zeigt, dass die Verwendung einer ausführlicheren Methode möglicherweise keine Bytes kostet.

Math.pow(2,53)-1

Das Obige kann jedoch kürzerMath ausfallen, wenn Sie sich beispielsweise bereits an einer anderen Stelle in Ihrem Code auf ein einzelnes Zeichen festgelegt haben.

Zottelig
quelle
2

Verwenden Sie Fraktionen anstelle von Float

Beispiel: 1./3anstelle von0.333333333

RosLuP
quelle