Search Unity

Big Numbers?

Discussion in 'Scripting' started by MyPix, Nov 22, 2015.

  1. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    Hello
    I Want to make a clicker game, but, how does the big number, like in Adventure Capitalist,are managed?
    Thanks
     
    brainykid50 likes this.
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Can't say for certain how other games handle it, there's probably info available via google, but I would create my own value structure for BigNumbers, using scientific notation... something like
    Code (CSharp):
    1. struct BigNumber {
    2.   public float coefficient;
    3.   public int exponent;
    4.  
    5.   public BigNumber (float c, int e) {
    6.     this.coefficient= v;
    7.     this.exponent = e;
    8.   }
    9.  
    10.   public static BigNumber operator + ( BigNumber a, BigNumber b ) {
    11.     return new BigNumber ( MATHS );
    12.   }
    13.  
    14. }
    then you just need to plug in all the MATHS for the various operators (add, subtract, multiply etc)
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    There are big number libraries out there that already roll everything for you.
    https://bignumber.codeplex.com/

    Furthermore, how big of numbers are we talking?

    .Net's built in 'Decimal' type has a sig value range of 28 decimal digits.
    https://msdn.microsoft.com/en-us/library/364x0z75.aspx

    So you could hold a whole number value as large as:
    10,000,000,000,000,000,000,000,000,000
    That's 10 octillion (short scale)

    If you needed a couple fractional values (maybe 2, if you're dealing with money), you just lose 2 of the upper limit sig values:
    100,000,000,000,000,000,000,000,000.00
    Still 100 septillion

    Like I said, not sure how large of a value you're looking for... but those appear pretty spanking big to me. And they're moderately fast compared to most big number implementations.
     
    Nigey likes this.
  4. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    I Know there is a BigInt with 64 Bit in .NET, but i'm talking, how does in Adventure Capitalist, were you reach number like Tredecillion, the numbers are stored ?
    Does the game Divide by 1000 the data everytime then change the notation?

    EDIT
    I think that's it, you store a double number, when it goes over 1000 you divide it by 1000 then upgrade the notation, so for, let's say, 234 333 111 111 (234 billion) in game you would have :
    234.33 Billion
    Internally you would have
    NUM = 234.333111111
    NOTATION = "Billion"

    It's mostly an array and some operator overloading
     
    Last edited: Nov 22, 2015
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    BigInt isn't in the version of .Net that we Unity uses.
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    As for reaching numbers in the size you're talking... when you have a Tredecillion... what does one thousand even mean anymore???

    double will go all the way up to 10^308. The only thing is it only has about 16 or so significant decimal figures.

    But when you're up at 10^48 (tredecillion), would you really be adding on values 16 factors of 10 smaller?
     
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I've managed this by chaining int64 together. You can get as high as you want without loosing any accuracy.

    Or you could just use a double and forget about precision. Ever wonder why the genre has a habit of displaying numbers as 4.167 Quantillion Zillion instead of 12343027458973409852289800000000000000000000001? Its not just a screen space issue.
     
    Kerith likes this.
  8. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    I Don't need really overprecision ^^
    For Double, i can just use them like normal variable, i don't need to implement something else ? (Like i just have a variable "double cookie" then just manage it ?)
     
    Kiwasi likes this.
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Yup, nothing special at all. You could even use a regular float instead if you can keep within the limits.
     
  10. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    Nice ! Now how do i display the big number in a short form ? (With the decillion & stuff)
     
  11. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
  12. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    If you're going to go the route of using some multiple ints to store the values in. You should make it a struct, and then override the 'ToString' method, and format accordingly.

    This is a custom type, you'll have to do the formatting manually.
     
  13. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    I Said earlier i'll go with the double as they can handle the numbers needed, i just need to know how to print the value in form of a text, or, how to get the exponent of the double and be able to get a literal out of this, is there any c# lib that convert double to a "readable" form like this ? (Decillion,Tredecellion,..)
     
  14. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
  15. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
  16. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    I Checked google before coming here thanks, your google results are completly useless to me.
     
  17. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    How are they useless?

    The first 4 links are people doing the very thing you want in .Net and discussing how they accomplished it.

    If their systems don't go high enough... expand it, add the values you want to it.
     
  18. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Didn't we mention this already? Its trivial, but a little tedious. Pseudo code follows.

    Code (CSharp):
    1. string [] prefixes = new string [3] {"thousand", "million", "billion"}
    2.  
    3. public string ConvertBigNumberToString (float bigNumber){
    4.     int noOfZeros = (int) Mathf.Log10(bigNumber);
    5.     int prefixIndex = (int) (noOfZeros / 3);
    6.     float displayNumber = bigNumber / (10 * 3 * prefixIndex);
    7.     return displayNumber.ToString () + " " + prefixes[prefixIndex];
    8. }
     
    lordofduct likes this.
  19. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Turns out I did.

    The code in that link is less psuedoish then the code I've just written above. I also go through a whole bunch of other considerations that apply when working with big numbers.
     
  20. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    Ah nice
    But for Displaynumber, the formula seems wrong
    Here is some examples of what i want

    123 000 000 000
    To be displayed as 123 Billions

    123 123 000 000
    To be displayed as 123.12 Billions

    1 123 000 000 000
    To be displayed as 1.12 Trillions
     
  21. Tastman

    Tastman

    Joined:
    Mar 12, 2015
    Posts:
    7
    I'm working on something like this. Using larger bit data types like Decimal won't work as in a clicker game you will typically reach numbers far higher than even a decimal variable supports.

    Here's what I'm using:

    Code (CSharp):
    1. string[] shortNotation = new string[12] {"", "k", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "Dc";
    2.  
    3. public string FormatEveryThirdPower(string[] notations, float target, string lowDecimalFormat)
    4.     {
    5.         float value = target;
    6.         int baseValue = 0;
    7.         string notationValue = "";
    8.         string toStringValue;
    9.  
    10.         if (value >= 10000) // I start using the first notation at 10k
    11.         {
    12.             value /= 1000;
    13.             baseValue++;
    14.             while (Mathf.Round((float)value) >= 1000)
    15.             {
    16.                 value /= 1000;
    17.                 baseValue++;
    18.             }
    19.  
    20.             if (baseValue < 2)
    21.                 toStringValue = "N1"; // display 1 decimal while under 1 million
    22.             else
    23.                 toStringValue = "N2"; // display 2 decimals for 1 million and higher
    24.  
    25.             if (baseValue > notations.Length) return null;
    26.             else notationValue = notations[baseValue];
    27.         }
    28.         else toStringValue = lowDecimalFormat; // string formatting at low numbers
    29.         return value.ToString(toStringValue) + notationValue;
    30.     }
    Then I just call it with my value display variable. FormatEveryThirdPower(shortNotation, myValue, "N0");
     
    Kiwasi likes this.
  22. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I said psuedo code. Its almost one in the morning. My ability to get the math right goes at about ten.

    @Tastman's implementation does essentially the same thing as mine. The process is pretty simple to implement on your own
    1. Count how many zeros the number has
    2. Choose an appropriate suffix from an array for the number of zeros
    3. Remove the extra zeros from the number
    4. Combine into a string
     
  23. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Yeah, but MyPix doesn't want to put any effort in.

    MyPix appears to want a premade script that with just a simple copy-paste it works exactly how MyPix expects it to work.

    Despite the fact that 1) it's trivial to write to your own tastes, and 2) the cultural implications of what numbers are 'named' means different people have personal tastes on it.

    Example... long vs short scale:
    https://en.wikipedia.org/wiki/Long_and_short_scales
     
  24. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    He, he. I was just reading that wikipedia page a second ago.

    There are enough people around asking to build an idle game that it might just be worth someones time to build a decent frame work for the asset store. The games are wildly popular, despite pretty much everything about them.
     
  25. Snownebula

    Snownebula

    Joined:
    Nov 29, 2013
    Posts:
    174
    Is it possible to do a long double vector3?
     
  26. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Sure, you can create a custom structure of type Vector3Dbl or some sort. Implement all the methods on it and what not.

    You could even make is serializable. And have implicit conversion with the unity Vector3.

    Thing is, the unity API would still use the single-float version, and you can't change that.
     
    Kiwasi likes this.
  27. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    I'm new to C# but i should be capable of writing this, thanks. Just asking questions. Omg
    I'll experiment;


    I'm working on something like this. Using larger bit data types like Decimal won't work as in a clicker game you will typically reach numbers far higher than even a decimal variable supports.

    Man, Double goes to 10^308, even AdCap doesnt go that far :p, i'm cool with a double :p
     
  28. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Note, there is 'range' and 'sig value range'.

    Double goes up to 10^308, but it's sig value range is only 16 decimal digits. Decimal has a range of 10^28, but a sig value range of 28 decimal digits. This is what I was attempting to say in my first post in this thread.
     
  29. MyPix

    MyPix

    Joined:
    Feb 23, 2014
    Posts:
    44
    Yeah i know, but like you said, i don't need up to 16 digits, if the users has 100 billions cookies i think 1 cookie does not mean anything to him anymore

    I Did a script that works tho, using the French notation of number (as my target is France & Belgium)
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4. using System.Globalization;
    5.  
    6. public class NumberFormatter : MonoBehaviour {
    7.  
    8.     public string[] shortNames = new string[20]
    9.     {
    10.          "Millions"     ,"Milliards",
    11.          "Billions"     ,"Billiards",
    12.          "Trillions"    ,"Trilliards",
    13.          "Quadrillions" ,"Quadrilliards",
    14.          "Quintillions" ,"Quintilliards",
    15.          "Sextillions"  ,"Sextilliards",
    16.          "Septillions"  ,"Septilliards",
    17.          "Octillions"   ,"Octilliards",
    18.          "Nonillions"   ,"Nonilliards",
    19.          "Decellions"   ,"Decilliards"
    20.     };
    21.  
    22.  
    23.     public string shortNotation(double value)
    24.     {
    25.         int nZeros      = (int)(Math.Log10(value));
    26.         int prefixIndex = (int)(((nZeros)/3));
    27.         prefixIndex-=2; // We delete the Thousand from the function to start with millions
    28.  
    29.  
    30.         if(nZeros < 6) // If under the Million, no need to convert
    31.             return value.ToString("0");
    32.         else if(prefixIndex>19) // Overflow..
    33.             prefixIndex = 19;
    34.  
    35.         string prefix = shortNames[prefixIndex];
    36.         double number = value/(Math.Pow(10,((prefixIndex+2)*3)));
    37.         string returnvalue = number.ToString("0.00");
    38.         returnvalue += " ";
    39.         returnvalue += prefix;
    40.         return returnvalue;
    41.     }
    42. }
    43.  
     
    glgamesforfun and rkvieira like this.