Hohe Zahlen mit Float/Int

  • Ich bastle grad an einem Game, bei dem es darum geht, eine Stadt aufzubauen, indem man Minen, Fabriken, Märkte, usw. baut und die Produkte an die Stadt bzw. Bewohner verkauft. (So eine Art Transport Gigant, aber nur mit Text und Zahlen).


    Mein Problem ist, dass Int bei ca. 2,147mia endet und wenn man float benutzt, werden irgendwann einige Zahlen übersprungen...


    Hier die Probleme mit Float:
    25.000.000.000 = 24.999.999.488
    1.000.000.000.000 = 999.999.995.904
    Soweit ist es ja noch nicht schlimm, sind halt ein paar Schweine vorm Schlachter abgehauen, das Problem sieht man aber erst, wenn man zwischen die großen Zahlen sieht.
    Zwischen der oben genannten Billion und diesem Wert "999.999.930.368" gibt es nämlich überhaupt nichts, da sind dann schon ein paar LKWs voll mit Schweinen verschwunden (oder wie durch Zauberhand dazu gekommen, denn es wird auch mal aufgerundet)
    Das Problem beginnt auch schon vor einer Million mit den Nachkommastellen...


    @Nobody hatte mir gesagt, dass man da anders arbeitet und zwar indem man z.B. einen Hunderter-Int nimmt, diesen bis 999 füllt und dann einen Tausender-Int anfängt, der wiederum bei 999 endet, usw.


    Leider bin ich zu dämlich, mit dieser Art von Rechnung umzugehen (vorallem bei Multiplizieren und Dividieren hab ich meine Probleme, z.B. beim berechnen was die nächste Stufe eines Gebäudeupgrades kostet, da das alles komplett automatisiert verläuft und somit theoretisch unendlich ist).
    Daher meine Frage an euch, gibt es ein Plugin oder irgendwas womit ich ein 2. Int einbauen kann, welches höher als nur bis zu den 2,147 Milliarden geht?
    Ich weiß, dass Twitter mal ein Problem mit genau dieser Zahl hatte, aber leider keine Ahnung, wie die das gelöst haben (hoffentlich nicht so wie Nobody es vorgeschlagen hat).


    Es wird natürlich auch eine Anzeigeart geben, wo die Nullen hinten dann bei 1 Million dann z.B. als E6 angezeigt werden und die Schweine dann nicht auffallen, aber ich weiß eben nicht, wie viele das Nutzen werden (ich jedenfalls nicht)...


    Falls jemand ein BP machen könnte, welches neben addieren und subtrahieren, auch noch multiplizieren und dividieren mit dem von @Nobody vorgeschlagenen System bewerkstelligt, würd ich mich sehr freuen, bei mir endet das grad immer nur im Chaos (vorallem bei höheren Zahlen ab 1Billion ... ich wage von den Quadrillionen gar nicht zu sprechen, hehe)^^


    Ja, ich hab mal wieder schlaflose Nächte, endlich alles fertig in Tabellen berechnet und alles fertig um das Spiel testbereit zu machen und dann macht das scheiss Int Probleme (Widgets und Actor sind das kleinere Problem)...
    Hatte eigentlich gehofft, das Spiel diese Woche für ein paar Tester raus zu bringen (mein erstes Spiel, ich freu mich richtig, hehe)^^

  • Eigentlich hast du die Lösung für dieses Problem ja schon selbst genannt.


    Du kannst dir das Vorstellen wie eine Art Spiele-Währung.
    Nehmen wir an, 1 Gold kostet 10000 Silber, 1 Silber kostet 10000 Kupfer, 1 Kupfer kostet 10000 Steine, dann könntest du mit 10000 Gold eine nichtmehr darstellbare Steinmenge ausdrücken.
    Du kannst jederzeit Preise festlegen, z.B. 400 Gold 256123 Silber 1532 Kupfer 3 Steine, und kannst dann diese 3 Währungen von deinen 3 Abziehen.


    Ebenso kannst du dein Gesamtvermögen Multiplizieren, indem Du jedes Einzelvermögen Multiplizierst.
    Wenn da jetzt eine Zahl größer als 10000 für Silber Rauskommen sollte (nehmen wir 10000 mal als Max an), dann kannst du einfach durch 10.000 Teilen, diese Nummer in Gold Reinstecken, und den Rest (mod) als Silber verbuchen.


    Du kannst das in beliebigen Dimensionen fortsetzen. Wichtig ist, dass du z.B. einen Max Wert von z.B. 10000 definierst. Das heißt, man kann maximal 10000 Einheiten von irgendwas haben. (ergibt 10001 mögliche Kombinationen wegen "0")

    Code
    Dimension(0) = "Steine"
    Dimension(1) = "Kupfer"
    Dimension(2) = "Silber"
    Dimension(3) = "Gold"
    Dimension(4) = "Diamant"
    Dimension(5) = "Menschenleben"
    Dimension(n) = "Was ganz tolles (n)"








    Das speicherst du dann z.B. in einem Array.
    In deinem Währungsarray hast du dann z.B.


    Code
    Array(0) = 3245 (Steine)
    Array(1) = 0 (Kupfer)
    Array(2) = 4523 (Silber)


    Wenn du jetzt dein Gesamtvermögen multiplizieren willst (*2) dann hast du

    Code
    (0) = 3245*2 = 6490 (Steine)
    (1) = 0*2 = 0 (Kupfer)
    (2) = 6666*2 = 13332 (Silberanteil = MOD(13332/10000[=Goldanteil=1]) = 3332 (Silber)
    (3) = 1 (Gold) (siehe oben (13332/10000) rest abschneiden)


    Du kannst also mit diesem Array beliebig große Zahlen darstellen. Ob du 10000er, 1000er, 100er Schritte wählst, spielt keine Rolle.


    Das ist quasi ähnlich einem Zahlensystem. Du kannst ja auch Hexadezimal mit weniger (aber komplexeren) Ziffern mehr Zahlen darstellen. Allerdings hast du nicht nur die Zahlen 0-9, sondern auch A-F als Zeichen. Hier ist das quasi so ähnlich, nur, dass du in diesem Fall 10.001 virtuelle Ziffern pro Stelle hast.


    Das heißt mir Array(0) (einer Ziffer) kannst du schon die Zahlen von 0-10000 Darstellen.



    Weiteres Beispiel:
    (Maximum = 999)



    Code
    Dimension(0) = "Euro"
    Dimension(1) = "TausendEuro"
    Dimension(2) = "MillionenEuro"
    Dimension(3) = "MilliardenEuro"
    Dimension(4) = "1000MilliardenEuro (ist das eine Billionen?^^)"

    Dimension(0) = 0
    Dimension(1) = 500
    Dimension(2) = 2
    Dimension(3) = 10
    Dimension(4) = 999



    Wert des Vermögens = StringMitNullen(Dimension(4))+"."+StringMitNullen(Dimension(3))+"."+StringMitNullen(Dimension(2))+"."+StringMitNullen(Dimension(1))+"."+StringMitNullen(Dimension(0))


    = 999.010.002.500.000 Euro



    Anmerkung: Die Funktion StringMitNullen wandelt die Zahl in einen String um und fügt noch Nullen ein Aus 10 wird also 010 und als 4 wird 004


    Vermögen *2 Rechnen


    Code
    Dimension(0) = 0*2 = 0
    Dimension(1) = 500 *2 = 0  (+1 Runter)
    Dimension(2) = 2 *2+1 = 5
    Dimension(3) = 10 *2 = 20
    Dimension(4) = 999 * 2 = 998 (+1 Runter)
    Dimension(5) = 1

    Wert des Vermögens = StringMitNullen(Dimension(5))+"."+StringMitNullen(Dimension(4))+"."+StringMitNullen(Dimension(3))+"."+StringMitNullen(Dimension(2))+"."+StringMitNullen(Dimension(1))+"."+StringMitNullen(Dimension(0))
    = 1.998.020.005.000.000 Euro




    Hoffe das war verständlich erklärt. :)


    MFG, Tank

  • Das muss ich mir morgen mal nochmal genauer angucken, z.Z. blick ich da überhaupt nicht durch, sollte eh langsam mal schlafen gehn^^

  • Das muss ich mir morgen mal nochmal genauer angucken, z.Z. blick ich da überhaupt nicht durch, sollte eh langsam mal schlafen gehn^^

    Sorry, wenn es etwas kompliziert erklärt ist x)


    Du musst quasi eine Art eigenes Zahlensystem bauen.


    Gute Beispiele sind Dual- und Hexadezimalsystem.

  • Dimension(4) = "1000MilliardenEuro (ist das eine Billionen?^^)"

    Ja ist es, wobei man da beim englischen und deutschen irgendwie durcheinander kommen kann, denn im englischen gibt es keine Milliarde, sondern nach Million kommt direkt Billion (englische Trillion ist deutsche Billion)^^

    Übrigens, mit Komma und Punkt muss man bei deutsch und englisch auch aufpassen, während es im deutschen, 1.000.000,00 ist, schreibt man es im englischen 1,000,000.00



    Das mit dem Array ist eigentlich ne ziemlich gute Idee, da bin ich nicht drauf gekommen...
    Ich versteh jetzt wie du es meinst, hatte aber noch keine Zeit das in der Praxis umzusetzen.


    Kannst du mir auch sagen wie das "StringMitNullen" auf englisch heißt, bevor ich mich dumm und dämlich suche?
    Hab keine Ahnung wie man das Devkit auf deutsch umstellt und es eigentlich auch nicht vor, hehe


    Edit: Grad eben gefunden, weil ich nach Sextillion nicht weiter wusste...

    3 Mal editiert, zuletzt von Killerzwerg ()

  • Mit dem Array geht es natürlich - das macht es aber schwerer zu benutzen. DU müsstest dir Eigne Funktionen bauen um damit zu rechnen - sihe mal Tankbusters Beispiel "vermögen mal zwei". In der Realität bekommst du ja es ja mit unbekannten INT oder Float zu tun gegen die du Addieren, Substrahieren, Dividieren und mutiplizieren willst (evtl. auch schlimmeres, COS/SIN TAN, etc). Sprich du musst dir ja erst mal ne eigene Mathe Library anlegen mit Funktionen die deine Arrays berechnen und dann nicht nur Array minus array, sondern evtl auch array minus int usw.


    Es gibt auch noch abstrusere Lösungen wie z.B. Koversation von Int in STRING und berechnung des Überlaufs, etc - aber das ist noch komplizierter und schwieriger und wohl nur ratsam wenn du Zahlen mit Tausen nullen oder so darstellen musst.


    Ich sehe hier 3 realistische Ansätze:


    1. König der Mathe Libraries. Wie gesagt libraries die deine Arrays in allen geschmacksrichtungen durchrechnen und auch brauchbare Ergebnisse dem Spieler Anzeigen.


    2. König von C++. Ja in C++ gibts auch so coole types wie INT64, UINT64 usw. Gibts aber nicht in Blueprint. Noch nicht. Leider.


    3. König der klassischen Games. Wie hat man es früher am Amiga und co gemacht? Unter 2 Milliarden geblieben. Nein für 2 Milliarden Schweine ist kein Platz in deiner Spielewelt, nicht mal für eine Milliarde. Häuser kosten 100,000 Euro und ein Auto 10,000 Euro. Komma und Cent gibt es nicht, basta. Das gesamt verfügbare gedruckte Geld ist 2 Milliarden und Schulden werden vom Staat verboten. Ja geht in Richtung geschummelt, aber wohl die einfachste Lösung. Zu mal viele Spieler dann 2000000000 und 20000000000 eh nicht unterscheiden können da das Hirn irgendwann bei der 6. oder 7. Stelle ins Straucheln kommt. Jaja, ich bin immer den Mann fürs billige also muß ich wohl nicht sagen welche der 3 Lösungen ich nehmen würde.

  • Hab mir das ganze mal im BP angeguckt und ist doch nicht ganz so einfach, denn ich müsste erstmal eine unbekannte Anzahl an Variablen aus dem Array speichern, dann aus dem 2. Array (was hinzugerechnet oder abgezogen werden soll) ebenfalls in einer unbekannten Anzahl Variablen speichern, dann alles berechnen, ans Widget als String ausspucken und danach wieder in ein Array stecken...
    Das wird bestimmt nicht wirklich gut sein für die Performance, vor allem wenn das irgendwann alle paar Sekunden ausgeführt werden muss^^



    1. König der Mathe Libraries. Wie gesagt libraries die deine Arrays in allen geschmacksrichtungen durchrechnen und auch brauchbare Ergebnisse dem Spieler Anzeigen.


    2. König von C++. Ja in C++ gibts auch so coole types wie INT64, UINT64 usw. Gibts aber nicht in Blueprint. Noch nicht. Leider.


    3. König der klassischen Gamess. Wie hat man es früher am Amiga und co gemacht? Unter 2 Milliarden geblieben. Nein für 2 Milliarden Schweine ist kein Platz in deiner Spielewelt, nicht mal für eine Milliarde. Häuser kosten 100,000 Euro und ein Auto 10,000 Euro. Komma und Cent gibt es nicht, basta. Das gesamt verfügbare gedruckte Geld ist 2 Milliarden und Schulden werden vom Staat verboten. Ja geht in Richtung geschummelt, aber wohl die einfachste Lösung. Zu mal viele Spieler dann 2000000000 und 20000000000 eh nicht unterscheiden können da das Hirn irgendwann bei der 6. oder 7. Stelle ins Straucheln kommt. Jaja, ich bin immer den Mann fürs billige also muß ich wohl nicht sagen welche der 3 Lösungen ich nehmen würde.

    1. Muss ich mir mal angucken
    2. Hab irgendwo mal gelesen, dass selbst wenn man in C++ dieses Int64 benutzt, es von der UE4 nicht verwertet werden kann... Und die Entwickler sehen keine Notwendigkeit, von Int32 auf Int64 umzubauen (beides gleichzeitig geht wohl nicht).
    3. Die erste Zeit wird keiner über eine Milliarde kommen, je länger das Spiel jedoch läuft, desto höher werden die Zahlen aber auch und da kann ich den Spieler nicht begrenzen, denn darin liegt ja der Sinn und Reiz eines Idle-Games, dass die Zahlen immer höher werden...
    Selbst wenn das Hirn bei 2000000000 abschaltet, wird es die Optionen geben, es als 2Mia oder 2E9 anzeigen zu lassen^^

  • Aber Schweine sterben doch oder werden geschlachtet. Warum sollte man so viele Schweine halten ;)
    Das UE4, zumindest per C++, kein Int64 unterstützt wundert mich allerdings. Aber wahrscheinlich meinst du die Nutzung in Blueprints oder z.B. der Anzeige des Wertes.
    Das es in Blueprints nicht zur verfügung steht und wohl auch nie kommen wird ist die "Systemabhängigkeit".
    Int64 oder Uint64 sind eben nicht auf allen Platformen verfügbar.
    Entwickelt man ein Spiel einzig auf Blueprintbasis soll das Ergebnis theoretisch ohne Anpassungen auf allen möglichen Platformen laufen.

  • Aber Schweine sterben doch oder werden geschlachtet. Warum sollte man so viele Schweine halten ;)
    Das UE4, zumindest per C++, kein Int64 unterstützt wundert mich allerdings. Aber wahrscheinlich meinst du die Nutzung in Blueprints oder z.B. der Anzeige des Wertes.
    Das es in Blueprints nicht zur verfügung steht und wohl auch nie kommen wird ist die "Systemabhängigkeit".
    Int64 oder Uint64 sind eben nicht auf allen Platformen verfügbar.
    Entwickelt man ein Spiel einzig auf Blueprintbasis soll das Ergebnis theoretisch ohne Anpassungen auf allen möglichen Platformen laufen.

    int64 wird über C++ unterstützt.
    Aber die anbindung zu Blueprint (falls man es benötigt) muss dann über eine eigene Klasse oder irgendeinem anderen Wrapper laufen, für die man entsprechende Blueprint funktionalitäten programmiert.
    Int64 gibts halt nicht in Blueprint. Also muss man jegliche Blueprint funktionalität für diesen Typ selber bauen.


    Wie es dann mit verschiedenen Plattformen aussieht ist vielleicht noch die Frage, aber ich glaube in modernen Plattformen gibts erst bei int128 Probleme.
    Normalerweise nutzt man aber in der Praxis int32 nichtmal komplett aus außer in sehr speziellen Anwendungen.


  • Als glühender Verfechter der "Wir machen das mit den Fähnchen" Lösung (Sparkassen Werbung...) würde ich das dann einfach so machen daß einer wenn er 2 Milliarden hat dann einfach eine abgezogen wird und er dafür einen "Tiberium Barren" bekommt. Wenn man das dann clever macht und das im profil des Spielers als "Stolze Errungenschaften" anzeigt dann meckert bestimmt auch keiner sondern die Leute denken sich "Krass der hat schon 2 Barren!". Die Verfehlungen einfach als Feature verkaufen! Bei 2 Milliarden Schweinen kann man dann ja ein "Platin Schwein" bekommen oder was auch immer. Und am Ende will jeder Platin oder Tiberium Trophäen.


    Aber gut lass dir von mir nix aufschwätzen, ich bin ein Freud der Workarounds und bekennendes faules Schwein. Hach wie gut daß wir sowieso gerade beim thema Schweine waren...

  • Hallo zusammen
    Das Problem scheint hier bereits gelöst.
    Dennoch ganz kurz, wenn Skalierung oder Normalisierung keine Option ist. Es geht hier wahrscheinlich um eine Art Score der im Playerstate gespeichert wird.
    Nun double etc. ist nicht im Bp unterstüzt, aber das ist ja auch kaum nötig oder. Die Zahl kann ja auch per String an das UI gesendet werden oder?
    Mit diesen Zahlen wirst du ausser Subtraktion und Addition kaum viel machen oder?

  • Freu mich grad richtig, hab das ganze jetzt endlich hin gekriegt, geht von 0,01 bis 999.999.999.999.999.999.999.999.999.999.999.999,99 (oder einfacher gesagt, bis Dezillionen im englischen und Quintilliarden im Deutschen).
    Das war jetzt echt ne schwere Geburt, hätte nicht gedacht dass ich das irgendwann mal hin kriege...
    Gut, hab bisher auch eher nur das ganze Design-technische und Daten in ner Tabelle gemacht^^


    Das einzige Limit ist jetzt grad das "Append String", welches man nur von A-Y füllen kann, aber die Zahlen sollten ja eigentlich auch reichen, zumindest erstmal, zur Not kann ichs immernoch mit nem 2., 3., 4., usw. "Append String" erweitern (wobei viel mehr Nullen kein Platz mehr haben ohne Zeilenumbruch), hehe
    Die Bilder sind evtl. bisschen unübersichtlich, hab das ganze in 6 Std zusammen geschustert, erledigt aber was es soll und das soll mir recht sein, auch wenn es automatisiert übersichtlicher wäre.

  • Danke,
    den schwierigsten Teil hab ich jetzt jedenfalls schon mal geschafft, hab aber keine Ahnung wielang ich daran noch arbeite, ist wie bei jedem meiner Projekte, erst super einfach und dann immer komplexer...
    (Keine Ahnung wie ich auf die Idee kam, aber es ist auch ein einstellbarer Wecker eingebaut, die Option zum auswählen verschiedener Wecktöne wirds auch noch geben)


    Mal sehn, vielleicht wirds bald mal ne Projektvorstellung geben^^
    Eigentlich könnte ichs auch demnächst releasen, das wichtigste was anfangs geplant war ist schon eingebaut, die restlichen Buttons zu den jeweiligen Menüs kann ich auch einfach ausblenden, aber da ich grad eh keine 100€ für Steam hab (Far Cry 5 Gold Edition ist schuld), ists grad egal.



    Achja, die Projektdateien haben grad mal 5mb, was fehlende Meshes und Texturen ausmachen können (Es gibt nur 2 Level und Widgets + Actor die unsichtbar in der Welt platziert werden)...

    Einmal editiert, zuletzt von Killerzwerg ()