Ich frage mich nur, wie Spiele wie Tap Titans und Cookie Clicker mit so großen Zahlen umgehen.
Ich versuche, ein Leerlaufspiel zu implementieren, aber das größte von C # unterstützte Zahlenformat ist dezimal.
Ich möchte bis zu 10 ^ 500 unterstützen. das muss Gleitkomma sein
Wie könnte ich damit umgehen?
PS: Es muss plattformübergreifend sein, dh PC, Mac, iOS, Android und mit Unity kompatibel
unity
mathematics
MathHelp
quelle
quelle
double
. Wenn ich es gewesen wäre, hätte ich allerdings BigInteger verwendet .Antworten:
Wenn Sie nur massive Zahlen ohne vollständige Genauigkeit speichern möchten, zum Beispiel 12.567.000.000.000 als 12.567T (Billionen) anzeigen möchten, können Sie einfach Standard-Gleitkomma- / Dezimalwerte verwenden und die ersten x signifikanten Ziffern mit einem geeigneten Suffix anzeigen so was. Müssen Sie sich wirklich um jedes einzelne ganzzahlige Inkrement kümmern, wenn Sie in den Achtecken sind?
quelle
Sie könnten so etwas wie BigInteger verwenden , das nur in .net 4.0 verfügbar ist, wenn ich mich nicht irre (nicht von allen Unity-Build-Plattformen unterstützt).
Es gibt einige Bibliotheken, die versuchen, diese Funktionalität ohne die Anforderung von .net4.0 bereitzustellen. Zum Beispiel hier .
Alternativ können Sie kleinere Zahlen verwenden, um eine größere darzustellen, indem Sie den Multiplikator verfolgen. Beispielsweise:
Auch wenn Sie jetzt einen Wert von 9 haben, können Sie ihn durch Koppeln mit Ihrem Multiplikator effektiv als 9 Billionen darstellen (entweder indem Sie "Billionen" eingeben oder etwas schreiben, das die Nullen am Ende Ihres Werts anfügt ).
quelle
BigInteger
String oder Byte [] als Repräsentation der Zahl verwenden - man kann also eine eigene Klasse erstellen, die nur zwei "Zahlen als Strings oder Bytes" addiert und subtrahiert - ( normalerweise ist dies bei dieser Art von Spiel nicht der Fall Sie brauchen es nicht, aber Sie könnten auch Multiplikation oder Division oder andere fortgeschrittenere Funktionen unterstützen ) - aber sie müssen bedenken, dass es immer eine physikalische Grenze gibt, an der ihnen möglicherweise der Speicher ausgeht.Sie müssten wahrscheinlich Ihre eigene Klasse schreiben, um sie in Unity zu verwenden, aber das wäre nicht besonders schwierig.
Intern kann es sich um eine Liste von Ganzzahlen handeln (z. B. a
List<int>
), wobei jedes Element in der Liste einer Gruppe von 9 Ziffern entspricht. Jede Ganzzahl hätte einen Bereich von 0 bis 999 999 999. Eine Ganzzahl kann etwas mehr als 2 Milliarden unterstützen und das Doppelte, wenn sie nicht vorzeichenbehaftet ist, aber Sie möchten, dass jede "Ziffer" überläuft1 000 000 000
, weil Sie es auch wollen in der Lage sein, Ihre große Zahl in eine Zeichenfolge für die Anzeige leicht umzuwandeln. Es ist einfacher zu verketten, was bereits Dezimalstellen (return group[i].ToString() + group[i-1].ToString() and so on
) sind, als herauszufinden, wie die Summe der Gruppen angezeigt wird, die außerhalb des Bereichs eines regulären Datentyps liegen.Das erste int in Ihrer Liste würde also 1s darstellen. Das nächste wäre die Anzahl der Milliarden. Das nächste, die Anzahl der Billiarden und so weiter.
Das Addieren und Subtrahieren funktioniert genauso wie das Addieren und Subtrahieren von Stift und Papier, bei dem auf Überlauf geachtet und zur nächsten "Ziffer" übertragen werden muss. Anstelle von Ziffern mit einem Bereich von 0 bis 9 reichen Ihre Ziffern jedoch von 0 bis 999 999 999.
quelle
Für den Umgang mit großen Zahlen würde ich mir das ansehen, was ich für ein gutes Beispiel wie Tower of Hero halte . Obere linke Ecke:
(Quelle: mzstatic.com )
Ohne ins Spiel zu kommen, ist der Umgang mit Zahlen relativ einfach: Sie sehen zwei Eimer mit Zahlen. Wenn Sie im Turm höher steigen und mehr "Gold" verdienen, repräsentieren die beiden Eimer einfach größere Zahlen.
Sobald das Spiel vorbei ist, bewegt es sich in a, b, c ... z, aa, ab, ...
Auf diese Weise wissen Sie immer noch, wie viel Gold Sie "verdient" haben, ohne das Spiel im Detail zu ruinieren.
Interessieren Sie sich wirklich für Millions, wenn Ihre Zahl über Trillions liegt?
Bleibt die Zahl in Int, Big Int, Float, Double, Decimal, ...? Benutzerdefiniertes Array? Wenn du mit Zahlen so "verschwommen" umgehst, denke ich nicht, dass es wichtig ist ...
Alles, was wahrscheinlich wichtig ist, sind die wichtigsten Teile - in diesem Fall die ersten 6 ... Danach MÖGLICHERWEISE die nächsten 3 oder 6 - da das Verdienen von ein paar hundert Kilometern in Millionen übergehen kann - aber es gibt einen Punkt, an dem das Verdienen beginnt Ein paar Hundert K werden Sie nicht beeinträchtigen, wenn Sie T drücken, geschweige denn aa und mehr.
Ihre Laufleistung variiert (je nachdem, was Sie wollen / brauchen) ... Ich dachte nur, ich würde meine 2c auf das setzen, was ich für ein gutes / einfaches Beispiel halte.
Bearbeiten:
Weitere Gedanken darüber, wie ich das Nummerierungssystem implementieren würde: Ich hätte eine Nummer mit 3 signifikanten Teilen: XXXX.YYY (...) xZZZ.
120.365x1 wäre also 120k365 ... 120.365x2 wäre 120M365K ... usw. Schlagen Sie die 4 führenden (1200.365x2) und drehen Sie dann einfach die Zahlen 1.200365 (...) x3. Bam. Sie haben 1B200M.
XY würde leicht in eine Dezimalzahl oder ein Float passen ... mit Z daneben als int / unsigned int.
Mit einem Float können Sie eine beträchtliche, aber zunehmend unwichtige Anzahl von Ziffern nach dem Punkt beibehalten.
Z würde den leicht verständlichen Zahlenblock darstellen:
quelle
Ein einfacher Weg, mit großen Zahlen umzugehen, besteht darin, mehr als einen INTEGER-Wert zu haben und dann einen eventuellen Überlauf zu CARRY. Wenn Sie einen 16-Bit-INT-Wert (0 bis 65535) haben und mehr möchten, verwenden Sie zwei 16-Bit-INT-Werte hintereinander. Stellen Sie sich vor, Sie hätten einen BYTE-Wert (0 bis 255), verwenden ihn jedoch nur bis zu 99 Stellen. Sobald der Wert 100 erreicht hat, rollen Sie ihn auf den nächsthöheren BYTE-Wert, und zwar für so viele Stellen, wie Sie für nützlich halten. Mit den heutigen GHZ-Computern ist auch eine solche schlampige Codierung in Ordnung.
Natürlich gibt es eine Alternative, die etwas schneller ist.
Wenn Sie einer Zahl wiederholt 18 hinzufügen, können Sie einfach 2 subtrahieren und 20 hinzufügen. 18, 36, 54, 72, 90, 108, ... 18 = 20 + (- 2).
Es funktioniert auch in Binary. (Gleiche Dezimalwerte in Binär) 10010, 100100, 110110, 1001000
DEC (18) = BIN (10010) Mit
Ausnahme der einfacheren Binäranalyse müssen Sie an 18 = 16 + 2
DEC (16 + 2) = BIN (10000 + denken 00010). Wenn der Wert 15 war, stellen Sie sich vor, Sie addieren 16 in binär und subtrahieren 1 (10000-00001).
Auf diese Weise können Sie die Anzahl der Chunks pro Wert auf ein überschaubares Maß beschränken.
Wenn Sie die schlampige Codierungsmethode zum Begrenzen eines 16-Bit-INT-Grundwerts (0 bis 65535) auf einen 4-stelligen Dezimalgrenzwert (0 bis 9999) verwenden, müssen Sie nur den Grenzwert 9999 überschreiten. subtrahiere 9999 davon und trage es zum nächsten Wert-Chunk (da du im Grunde genommen "addiere & subs" mit Zahlen gegenüber einer reellen Binärberechnung machst).
Idealerweise verwenden Sie nur SYMBOLISCHE MATHE, die Sie in der Grundschule gelernt haben. Wie funktioniert das. Wenn Sie das Dezimalsymbol von 1 haben und es zu 1 addieren, erhalten Sie das Dezimalsymbol von 2. Der Grund, warum ich dies als Symbol bezeichne, ist, dass Sie jede Symbolserie mit einer Nachschlagetabelle von "IF symbol X (1)" verwenden können. wird zum Symbol X (4) DANN zum Ausgangssymbol X (5) "hinzugefügt. Symbol X (1) könnte ein Bild einer Katze sein, und Symbol X (4) könnte das Prozentzeichen sein, aber es spielt keine Rolle. Sie haben Ihre Symbole, ein grundlegendes Regelwerk darüber, was passiert, wenn diese Symbole kombiniert werden (ähnlich wie die Multiplikationstabellen, die Sie als Kind gespeichert haben) und welches Symbol als Teil dieser Operation resultieren muss. Mit Symbolic Math können Sie eine unbegrenzte Anzahl von Ziffern hinzufügen, ohne die numerischen Grenzen Ihres Prozessors wirklich zu überschreiten.
Eine Möglichkeit, dies bei der einfachen Codierung zu tun, besteht darin, jede dargestellte Ziffer, mit der Sie arbeiten möchten, als einzelne Einheit in einem Array mit großen Abmessungen darzustellen. Wenn Sie 4096 Dezimalstellen darstellen möchten (maximal 2 Stellen pro Einheit), weisen Sie 2 Sätze mit 4096 BYTE-Array-Positionen zu. Das Speichern des Wertes von 1098874 würde das Array als (1) (0) (9) (8) (8) (7) (4) verwenden. Wenn Sie den Wert 7756 dazu addieren, konvertieren Sie ihn in (7) (7) (5) (6) und addieren dann. Das Ergebnis wäre (1) (0) (9) (15) (15) (12) (10), und Sie würden dann die Verschiebung von rechts nach links subtrahieren, bis alle Ziffernfelder auf den Wert von (0 bis) normiert wurden 9). Der am weitesten rechts stehende Wert (10) würde 10 subtrahieren und der resultierende Wert wäre Null (0), und das würde den Wert (1) in das nächste linke Kästchen von (12) tragen, um daraus (13) zu machen, das dann 10 hätte subtrahiert, um es in (3) zu machen.
quelle
`text`
→text
) einschließen, wird er in einem einheitlichen Abstand angezeigt, der für Codestücke , Funktionsnamen, Daten usw. geeignet ist. Wenn Sie Text in Unterstriche oder Sternchen einschließen, wird er kursiv (_text_
oder*text*
→ Text ) und doppelt unterstrichen oder doppelt unterstrichen. Sternchen machen es fett (__text__
oder**text**
→ Text ).Sie können mehrere Variablen kombinieren und dann die Addition und den Überlauf zwischen ihnen selbst steuern. Sie können auf diese Weise eine beliebige Anzahl von Ziffern eingeben. Kombinieren Sie 10.000 32-Bit-Ganzzahlen, und Sie haben eine Zahl mit 32.000 Bits, wenn Sie dies benötigen. In jeder Programmiersprache gibt es keine Grenzen. Die einzige Grenze ist, was Sie herausfinden können.
quelle
double
oder nicht unterstützenBigInteger
.