- Home /
Using Very Large Numbers and Prefixes // For an Idle Game e100,e1000, and more.
Hi. So I made a sample code to make a never-ending number prefix system. The problem is that the code can get super long if I copy and paste a thousand times and I have no idea on how to automate this script with only a few lines of code. Here is the code.
if (num >= 1000)
{
e1num = num / 1000;
numText.text = "" + e1num.ToString("F2") + "e3" ;
}
if (e1num >= 10)
{
e2num = e1num / 10;
numText.text = "" + e2num.ToString("F2") + "e4";
}
if (e2num >= 10)
{
e3num = e2num / 10;
numText.text = "" + e3num.ToString("F2") + "e5";
}
if (e3num >= 10)
{
e4num = e3num / 10;
numText.text = "" + e4num.ToString("F2") + "e6";
}
if (e4num >= 10)
{
e5num = e4num / 10;
numText.text = "" + e5num.ToString("F2") + "e7";
}
if (e5num >= 10)
{
e6num = e5num / 10;
numText.text = "" + e6num.ToString("F2") + "e8";
}
if (e6num >= 10)
{
e7num = e6num / 10;
numText.text = "" + e7num.ToString("F2") + "e9";
}
if (e7num >= 10)
{
e8num = e7num / 10;
numText.text = "" + e8num.ToString("F2") + "e10";
}
if (e8num >= 10)
{
e9num = e8num / 10;
numText.text = "" + e9num.ToString("F2") + "e11";
}
if (e9num >= 10)
{
e10num = e9num / 10;
numText.text = "" + e10num.ToString("F2") + "e12";
}
num is the first number variable for 1-10000, (only display when the value is 1-1000). e1num is e3 and displays 1000-10000. e2num is e4 and displays 10000-100000. and this goes on 8 more times. I don't want to do this 992 more times in order to hit e1000. Do you guys think you can help me find a way to shrink this script so it can be never-ending and very easy to read and change (variable names and text such as "e3", I want to prevent having to copy and paste variables 20 times like my previous script. Thanks, NightGrounds/ZachAttack9280.
if(num>=1000)
{e1num=num/1000;numText.text=""+e1num.ToString("F2")+"e3";}
if(e1num>=10)
{e2num=e1num/10;numText.text=""+e2num.ToString("F2")+"e4";}
if(e2num>=10)
{e3num=e2num/10;numText.text=""+e3num.ToString("F2")+"e5";}
if(e3num>=10)
{e4num=e3num/10;numText.text=""+e4num.ToString("F2")+"e6";}
if(e4num>=10)
{e5num=e4num/10;numText.text=""+e5num.ToString("F2")+"e7";}
if(e5num>=10)
{e6num=e5num/10;numText.text=""+e6num.ToString("F2")+"e8";}
if(e6num>=10)
{e7num=e6num/10;numText.text=""+e7num.ToString("F2")+"e9";}
if(e7num>=10)
{e8num=e7num/10;numText.text=""+e8num.ToString("F2")+"e10";}
if(e8num>=10)
{e9num=e8num/10;numText.text=""+e9num.ToString("F2")+"e11";}
if(e9num>=10)
{e10num=e9num/10;numText.text=""+e10num.ToString("F2")+"e12";}
$$anonymous$$ified, still will become long and tiring in the long term. ^^
Answer by JDelekto · Jun 27, 2018 at 11:03 AM
Note that while this will incur rounding error and you will lose precision, the easiest way to do this in a one-liner is to use the built in custom string formatting to format the string as an exponent with the decimal places that you want.
numText.text = string.Format((num < 1000) ? "{0:F3}" : "{0:0.00e0}", num);
Alright, I tried that out and I'm running into the same problem as I have been trying to solve, the dividing part. Basically, the highest number I can go to is 3.40e38 but I would like to go higher. I'm still trying to find a way I can simply divide e30 or e10 of it so I can go higher.
If you have ever played or heard of Best Fiends Forever, it's an idle game that has, multiple coins, bronze, silver, and gold (and maybe more). Once you hit 1 trillion bronze, the game currency turns into 1 silver and so on. I am trying to do the same thing just without the extra currencies (bronze, silver, and gold).
Hope that makes sense
And if you look at this other idle game, numbers can reach up to e10000 or even e500000
I looked at the game, they apparently have an interesting way of doing this using Decimal values (C# does have a Decimal type BTW).
If you're interesting in seeing how they do it, the JavaScript source code for Antimatter Dimensions can be found in the following GitHub repository: https://github.com/Ivar$$anonymous$$/Ivar$$anonymous$$.github.io
You should be able to adapt something to C#.
Another issue...
The console displays the number correctly but not that text and the variable in the inspector. How can I fix this?
Answer by Bunny83 · Jun 27, 2018 at 08:41 AM
You missed an important fact about your number. Which type is "num"? You know that an int (which is an Int32) only goes up to 2,147,483,647
the unsigned uint up to 4,294,967,295
. If you use a long (which is an Int64) the number goes up to 9,223,372,036,854,775,807
and the unsigned version ulong up to 18,446,744,073,709,551,615
. So even with an ulong you are bound to max "e19".
So you can't store an infinite large number in any data type that has a fix length / size. Even when using double as datatype the range is limited and more important the precision decreases the larger the number gets. That means changes that are too small may not be recognised and rounded to 0. I've posted a table for the float data type over here.
If you actually work with integer numbers you could use an infinite integer struct which stores it's value inside an array which can grow as necessary. For example BigInteger
Apart from how you want to store you number you can directly determine the base 10 exponent of a number by calculating the base 10 log of your number and round it down to the nearest integer. The BigInteger has a dedicated Log10 method.
Note that solutions like the BigInteger have quite a bit of overhead the larger the number gets. It shouldn't be too bad if you have just a couple of them.
What solution might be the best for you depends on your relative sizes of the numbers you work with. Sometimes it's enough to use a hybrid of an ulong and a double value. You should think about your max increase and what's the max required range you may need. For example if you use an ulong value that you increase by 10000 every frame at 60 fps it would take 974904 years to run out of digits. However if your relative increase should itself increase over time simply using a double might be enough. We don't know enough about your conditions to give a clear answer.
If you're really just interested in how you can simplify your original code there are two ways:
int exp = (int)System.$$anonymous$$ath.Log10(num);
int val = (int)(num / System.$$anonymous$$ath.Pow(10, exp));
numText.text = "" + val + "e" + exp;
Or if you want to keep your current approach just automate it, use a loop
var val = num;
if (val < 1000)
{
numText.text = val.ToString("F3");
}
else
{
int exp = 3;
val /= 1000;
while (val > 10)
{
val /=10;
exp++;
}
numText.text = val.ToString("F2") + "e" + exp;
}
Yeah, I see what you mean, I am currently using a float. In your code, exp++ basically adds one to the variable? Sorry Looks like JS and I am currently working with C# (oops another thing I forgot to mention...)
Answer by ZachAttack9280 · Jun 27, 2018 at 10:56 PM
I'm still pretty confused honestly :/
So I tried this but now the max is e308 which is a huge benefit, although, if I can still somehow go higher, that would be awesome. Otherwise, I think I got what I'm looking for.
BTW, I was mistaken about the Decimal... it is not intrinsic to JavaScript and not the same as the C# decimal.
The game I mentioned actually uses a library called "break_infinity.js" (https://github.com/Patashu/break_infinity.js) which defines the decimal class. It is based on decimal.js and as they describe:
replacement for decimal.js for incremental games who want to deal with very large numbers (bigger in magnitude than 1e308, up to as much as 1e(9e15) ) and want to prioritize speed over accuracy.*
So, it is basically a modified version of decimal.js (https://github.com/$$anonymous$$ike$$anonymous$$cl/decimal.js) which is an arbitrary-precision Decimal type created for JavaScript that is meant to be optimized for speed.
Let's just say that it is quite a bit of work if you want to use this approach and you may want to consider seeing if you can find a similar package or port of either of the JavaScript approaches you can use.
However, there isn't a simple and straightforward answer to your question other than using a 3rd party package to supply this functionality.
I guess I'll just stick with the e308 limit and add some kind of new game mechanic for whenever the max is hit.
Your answer
![](https://koobas.hobune.stream/wayback/20220612165554im_/https://answers.unity.com/themes/thub/images/avi.jpg)