How to store and work with REALLY big numbers in Unity?

So I am making a code that is supposed to allow it to parse/seperate variables into more human readable without the E13 etc at the end, so I made a Class to store the values of each area, ie single digits, thousands, millions, etc, each with there own variable, and a function to parse/check to see if for example more the 1000 exists in the thousands, to add one to the millions, then take away from the thousands.
I am sure there is a better way to do it but I didnt see any examples of doing it so kinda just winging it.
The second part reads the values and returns a string with the correct amount upto 2 sections, ie can say you have 1million 57 thousand returned as a string.
On the first part, parsing it out to other variables seems kinda long and alota while loops, the second part to make the string seems i have way to complicated it.
The code does work, just wondering if there would be a better way to make it work without so much while loops or if statements, so just looking for other ideas on how to make it work more efficient, like if I can use cases or diffrent commands to merge some of the lines instead of so many solo parts.
I know all the public ulong variables can be combined, but atm just that way so its easier for me to find them and see how there spelled since some are close to others.
So here is the class in question, again the code does work, I can get the variables from it right just think im making it to complicated.

public class moneyForm
{
    public ulong single;
    public ulong thousand;
    public ulong million;
    public ulong billion;
    public ulong trillion;
    public ulong quadrillion;
    public ulong quintillion;
    public ulong hextillion;
    public ulong septillion;
    public ulong Octillion;
    public ulong Nonillion;
    public ulong Decillion;
    public ulong Undecillion;
    public ulong Duodecillion;
    public ulong Tredecillion;
    public ulong Quattuordecillion;
    public ulong Quindecillion;
    public ulong Hexdecillion;
    public ulong Septendecillion;
    public ulong Octodecillion;
    public ulong Novemdecillion;
    public ulong Vigintillion;
    public ulong Unvigintillion;
    public ulong Duovigintillion;
    public ulong Trevigintillion;
    public ulong Quattourvigintillion;
    public ulong Quinvigintillion;
    public ulong Hexvigintillion;
    public ulong Septenvigintillion;
    public ulong Octovigintillion;
    public ulong Novemvigintillion;
    public ulong Trigintillion;
    public ulong Untrigintillion;
    public ulong Duotrigintillion;
    public ulong Googol;
    public ulong Googolplex;
    public void ParseNumbers()
    {
        while (this.single >= 1000)
        {
            this.thousand++;
            this.single = Convert.ToUInt64(this.single - 1000);
        }
        while (this.thousand >= 1000)
        {
            this.million++;
            this.thousand = Convert.ToUInt64(this.thousand - 1000);
        }
        while (this.million >= 1000)
        {
            this.billion++;
            this.million = Convert.ToUInt64(this.million - 1000);
        }
        while (this.billion >= 1000)
        {
            this.trillion++;
            this.billion = Convert.ToUInt64(this.billion - 1000);
        }
        while (this.trillion >= 1000)
        {
            this.quadrillion++;
            this.trillion = Convert.ToUInt64(this.trillion - 1000);
        }
        while (this.quadrillion >= 1000)
        {
            this.quintillion++;
            this.quadrillion = Convert.ToUInt64(this.quadrillion - 1000);
        }
        while (this.quintillion >= 1000)
        {
            this.hextillion++;
            this.quintillion = Convert.ToUInt64(this.quintillion - 1000);
        }
        while (this.hextillion >= 1000)
        {
            this.septillion++;
            this.hextillion = Convert.ToUInt64(this.hextillion - 1000);
        }
        while (this.septillion >= 1000)
        {
            this.Octillion++;
            this.septillion = Convert.ToUInt64(this.septillion - 1000);
        }
        while (this.Octillion >= 1000)
        {
            this.Nonillion++;
            this.Octillion = Convert.ToUInt64(this.Octillion - 1000);
        }
        while (this.Nonillion >= 1000)
        {
            this.Decillion++;
            this.Nonillion = Convert.ToUInt64(this.Nonillion - 1000);
        }
        while (this.Decillion >= 1000)
        {
            this.Undecillion++;
            this.Decillion = Convert.ToUInt64(this.Decillion - 1000);
        }
        while (this.Undecillion >= 1000)
        {
            this.Duodecillion++;
            this.Undecillion = Convert.ToUInt64(this.Undecillion - 1000);
        }
        while (this.Duodecillion >= 1000)
        {
            this.Tredecillion++;
            this.Duodecillion = Convert.ToUInt64(this.Duodecillion - 1000);
        }
        while (this.Tredecillion >= 1000)
        {
            this.Quattuordecillion++;
            this.Tredecillion = Convert.ToUInt64(this.Tredecillion - 1000);
        }
        while (this.Quattuordecillion >= 1000)
        {
            this.Quindecillion++;
            this.Quattuordecillion = Convert.ToUInt64(this.Quattuordecillion - 1000);
        }
        while (this.Quindecillion >= 1000)
        {
            this.Hexdecillion++;
            this.Quindecillion = Convert.ToUInt64(this.Quindecillion - 1000);
        }
        while (this.Hexdecillion >= 1000)
        {
            this.Septendecillion++;
            this.Hexdecillion = Convert.ToUInt64(this.Hexdecillion - 1000);
        }
        while (this.Septendecillion >= 1000)
        {
            this.Octodecillion++;
            this.Septendecillion = Convert.ToUInt64(this.Septendecillion - 1000);
        }
        while (this.Octodecillion >= 1000)
        {
            this.Novemdecillion++;
            this.Octodecillion = Convert.ToUInt64(this.Octodecillion - 1000);
        }
        while (this.Novemdecillion >= 1000)
        {
            this.Vigintillion++;
            this.Novemdecillion = Convert.ToUInt64(this.Novemdecillion - 1000);
        }
        while (this.Vigintillion >= 1000)
        {
            this.Unvigintillion++;
            this.Vigintillion = Convert.ToUInt64(this.Vigintillion - 1000);
        }
        while (this.Unvigintillion >= 1000)
        {
            this.Duovigintillion++;
            this.Unvigintillion = Convert.ToUInt64(this.Unvigintillion - 1000);
        }
        while (this.Duovigintillion >= 1000)
        {
            this.Trevigintillion++;
            this.Duovigintillion = Convert.ToUInt64(this.Duovigintillion - 1000);
        }
        while (this.Trevigintillion >= 1000)
        {
            this.Quattourvigintillion++;
            this.Trevigintillion = Convert.ToUInt64(this.Trevigintillion - 1000);
        }
        while (this.Quattourvigintillion >= 1000)
        {
            this.Quinvigintillion++;
            this.Quattourvigintillion = Convert.ToUInt64(this.Quattourvigintillion - 1000);
        }
        while (this.Quinvigintillion >= 1000)
        {
            this.Hexvigintillion++;
            this.Quinvigintillion = Convert.ToUInt64(this.Quinvigintillion - 1000);
        }
        while (this.Hexvigintillion >= 1000)
        {
            this.Septenvigintillion++;
            this.Hexvigintillion = Convert.ToUInt64(this.Hexvigintillion - 1000);
        }
        while (this.Septenvigintillion >= 1000)
        {
            this.Octovigintillion++;
            this.Septenvigintillion = Convert.ToUInt64(this.Septenvigintillion - 1000);
        }
        while (this.Octovigintillion >= 1000)
        {
            this.Novemvigintillion++;
            this.Octovigintillion = Convert.ToUInt64(this.Octovigintillion - 1000);
        }
        while (this.Novemvigintillion >= 1000)
        {
            this.Trigintillion++;
            this.Novemvigintillion = Convert.ToUInt64(this.Novemvigintillion - 1000);
        }
        while (this.Trigintillion >= 1000)
        {
            this.Untrigintillion++;
            this.Trigintillion = Convert.ToUInt64(this.Trigintillion - 1000);
        }
        while (this.Untrigintillion >= 1000)
        {
            this.Duotrigintillion++;
            this.Untrigintillion = Convert.ToUInt64(this.Untrigintillion - 1000);
        }
        while (this.Duotrigintillion >= 1000)
        {
            this.Googol++;
            this.Duotrigintillion = Convert.ToUInt64(this.Duotrigintillion - 1000);
        }
        while (this.Googol >= 1000)
        {
            this.Googolplex++;
            this.Googol = Convert.ToUInt64(this.Googol - 1000);
        }
        while (this.Googolplex >= 1000)
        {
            // O_O Wow thats a big number we need to make something larger
            this.Googolplex = Convert.ToUInt64(this.Googolplex - 1000);
        }
    }

    public string GetValue()
    {
        string temp1 = "";
        if (this.Googolplex >= 1) { temp1 = (this.Googolplex + " GoogolPlex "); if (this.Googol >= 1) { temp1 += (this.Googol + " Googol"); } return (temp1); }
        if (this.Googol >= 1) { temp1 = (this.Googol + " Googol "); if (this.Duotrigintillion >= 1) { temp1 += (this.Duotrigintillion + " Duotrigintillion"); } return (temp1); }
        if (this.Duotrigintillion >= 1) { temp1 = (this.Duotrigintillion + " Duotrigintillion "); if (this.Untrigintillion >= 1) { temp1 += (this.Untrigintillion + " Untrigintillion"); } return (temp1); }
        if (this.Untrigintillion >= 1) { temp1 = (this.Untrigintillion + " Untrigintillion "); if (this.Trigintillion >= 1) { temp1 += (this.Trigintillion + " Trigintillion"); } return (temp1); }
        if (this.Trigintillion >= 1) { temp1 = (this.Trigintillion + " Trigintillion "); if (this.Novemvigintillion >= 1) { temp1 += (this.Novemvigintillion + " Novemvigintillion"); } return (temp1); }
        if (this.Novemvigintillion >= 1) { temp1 = (this.Novemvigintillion + " Novemvigintillion "); if (this.Octovigintillion >= 1) { temp1 += (this.Octovigintillion + " Octovigintillion"); } return (temp1); }
        if (this.Octovigintillion >= 1) { temp1 = (this.Octovigintillion + " Octovigintillion "); if (this.Septenvigintillion >= 1) { temp1 += (this.Septenvigintillion + " Septenvigintillion"); } return (temp1); }
        if (this.Septenvigintillion >= 1) { temp1 = (this.Septenvigintillion + " Septenvigintillion "); if (this.Hexvigintillion >= 1) { temp1 += (this.Hexvigintillion + " Hexvigintillion"); } return (temp1); }
        if (this.Hexvigintillion >= 1) { temp1 = (this.Hexvigintillion + " Hexvigintillion "); if (this.Quinvigintillion >= 1) { temp1 += (this.Quinvigintillion + " Quinvigintillion"); } return (temp1); }
        if (this.Quinvigintillion >= 1) { temp1 = (this.Quinvigintillion + " Quinvigintillion "); if (this.Quattourvigintillion >= 1) { temp1 += (this.Quattourvigintillion + " Quattourvigintillion"); } return (temp1); }
        if (this.Quattourvigintillion >= 1) { temp1 = (this.Quattourvigintillion + " Quattourvigintillion "); if (this.Trevigintillion >= 1) { temp1 += (this.Trevigintillion + " Trevigintillion"); } return (temp1); }
        if (this.Trevigintillion >= 1) { temp1 = (this.Trevigintillion + " Trevigintillion "); if (this.Duovigintillion >= 1) { temp1 += (this.Duovigintillion + " Duovigintillion"); } return (temp1); }
        if (this.Duovigintillion >= 1) { temp1 = (this.Duovigintillion + " Duovigintillion "); if (this.Unvigintillion >= 1) { temp1 += (this.Unvigintillion + " Unvigintillion"); } return (temp1); }
        if (this.Unvigintillion >= 1) { temp1 = (this.Unvigintillion + " Unvigintillion "); if (this.Vigintillion >= 1) { temp1 += (this.Vigintillion + " Vigintillion"); } return (temp1); }
        if (this.Vigintillion >= 1) { temp1 = (this.Vigintillion + " Vigintillion "); if (this.Novemdecillion >= 1) { temp1 += (this.Novemdecillion + " Novemdecillion"); } return (temp1); }
        if (this.Novemdecillion >= 1) { temp1 = (this.Novemdecillion + " Novemdecillion "); if (this.Octodecillion >= 1) { temp1 += (this.Octodecillion + " Octodecillion"); } return (temp1); }
        if (this.Octodecillion >= 1) { temp1 = (this.Octodecillion + " Octodecillion "); if (this.Septendecillion >= 1) { temp1 += (this.Septendecillion + " Septendecillion"); } return (temp1); }
        if (this.Septendecillion >= 1) { temp1 = (this.Septendecillion + " Septendecillion "); if (this.Hexdecillion >= 1) { temp1 += (this.Hexdecillion + " Hexdecillion"); } return (temp1); }
        if (this.Hexdecillion >= 1) { temp1 = (this.Hexdecillion + " Hexdecillion "); if (this.Quindecillion >= 1) { temp1 += (this.Quindecillion + " Quindecillion"); } return (temp1); }
        if (this.Quindecillion >= 1) { temp1 = (this.Quindecillion + " Quindecillion "); if (this.Quattuordecillion >= 1) { temp1 += (this.Quattuordecillion + " Quattuordecillion"); } return (temp1); }
        if (this.Quattuordecillion >= 1) { temp1 = (this.Quattuordecillion + " Quattuordecillion "); if (this.Tredecillion >= 1) { temp1 += (this.Tredecillion + " Tredecillion"); } return (temp1); }
        if (this.Tredecillion >= 1) { temp1 = (this.Tredecillion + " Tredecillion "); if (this.Duodecillion >= 1) { temp1 += (this.Duodecillion + " Duodecillion"); } return (temp1); }
        if (this.Duodecillion >= 1) { temp1 = (this.Duodecillion + " Duodecillion "); if (this.Undecillion >= 1) { temp1 += (this.Undecillion + " Undecillion"); } return (temp1); }
        if (this.Undecillion >= 1) { temp1 = (this.Undecillion + " Undecillion "); if (this.Decillion >= 1) { temp1 += (this.Decillion + " Decillion"); } return (temp1); }
        if (this.Decillion >= 1) { temp1 = (this.Decillion + " Decillion "); if (this.Nonillion >= 1) { temp1 += (this.Nonillion + " Nonillion"); } return (temp1); }
        if (this.Nonillion >= 1) { temp1 = (this.Nonillion + " Nonillion "); if (this.Octillion >= 1) { temp1 += (this.Octillion + " Octillion"); } return (temp1); }
        if (this.Octillion >= 1) { temp1 = (this.Octillion + " Octillion "); if (this.septillion >= 1) { temp1 += (this.septillion + " septillion"); } return (temp1); }
        if (this.septillion >= 1) { temp1 = (this.septillion + " septillion "); if (this.hextillion >= 1) { temp1 += (this.hextillion + " hextillion"); } return (temp1); }
        if (this.hextillion >= 1) { temp1 = (this.hextillion + " hextillion "); if (this.quintillion >= 1) { temp1 += (this.quintillion + " quintillion"); } return (temp1); }
        if (this.quintillion >= 1) { temp1 = (this.quintillion + " quintillion "); if (this.quadrillion >= 1) { temp1 += (this.quadrillion + " quadrillion"); } return (temp1); }
        if (this.quadrillion >= 1) { temp1 = (this.quadrillion + " quadrillion "); if (this.trillion >= 1) { temp1 += (this.trillion + " trillion"); } return (temp1); }
        if (this.trillion >= 1) { temp1 = (this.trillion + " trillion "); if (this.billion >= 1) { temp1 += (this.billion + " billion"); } return (temp1); }
        if (this.billion >= 1) { temp1 = (this.billion + " billion "); if (this.million >= 1) { temp1 += (this.million + " million"); } return (temp1); }
        if (this.million >= 1) { temp1 = (this.million + " million "); if (this.thousand >= 1) { temp1 += (this.thousand + " thousand"); } return (temp1); }
        if (this.thousand >= 1) { temp1 = (this.thousand + " thousand "); if (this.single >= 1) { temp1 += (this.single + ""); } return (temp1); }
        if (this.single >= 1) { temp1 = (this.single + ""); return (temp1); }
        return ("0");
    }
}

}

Here’s a way of creating the string mathematically rather than by hand;

using System;
using System.Text;
using UnityEngine;

public static class NumberFormatter
{
	public static readonly string[] Units = new string[]
	{
		"Single",
		"Thousand",
		"Million",
		"Billion",
		"Trillion",
		"Quadrillion",
		"Quintillion",
		"Hextillion",
		"Septillion",
		"Octillion",
		"Nonillion",
		"Decillion",
		"Undecillion",
		"Duodecillion",
		"Tredecillion",
		"Quattuordecillion",
		"Quindecillion",
		"Hexdecillion",
		"Septendecillion",
		"Octodecillion",
		"Novemdecillion",
		"Vigintillion",
		"Unvigintillion",
		"Duovigintillion",
		"Trevigintillion",
		"Quattourvigintillion",
		"Quinvigintillion",
		"Hexvigintillion",
		"Septenvigintillion",
		"Octovigintillion",
		"Novemvigintillion",
		"Trigintillion",
		"Untrigintillion",
		"Duotrigintillion",
		"Googol",
		"Googolplex"
	};

	public static string Parse (ulong a_Number)
	{
		// Early out on 0
		if (a_Number == 0)
		{
			return "0";
		}

		// Technically 'number of digits minus 1'
		int digits = (int)Math.Log10 (a_Number);
		// 0-based index of the largest unit
		int unit = digits / 3;

		// Failsafe incase we can't handle the input
		if (unit >= Units.Length)
		{
			Debug.LogError ("[NumberFormatter] Number was too big!");
			return a_Number.ToString ();
		}
		
		// System.Text.StringBuilder is way more efficient for combining strings than regular concatenation
		StringBuilder sb = new StringBuilder ();
		// Iterate backwards through every unit greater than Single
		for (int i = unit; i > 0; i--)
		{
			// Find the current unit numerically
			ulong nearestUnit = (ulong)Math.Pow (10, i * 3);
			// How many of the current unit fits into our number
			ulong current = a_Number / nearestUnit;

			// If the number is smaller than the current unit, skip it
			if (current > 0)
			{
				// If this isn't the first number add a comma
				if (i < unit)
				{
					sb.Append (", ");
				}

				// Add the number of the current unit and find its name in the array
				sb.Append ($"{current} {Units*}");*
  •  		// Move on to the next unit*
    

a_Number -= current * nearestUnit;

  •  	}*
    
  •  }*
    
  •  // Add the Single value last if we have it*
    
  •  if (a_Number > 0)*
    
  •  {*
    
  •  	// If this is the last unit and we still have a Single left, add an 'and'*
    
  •  	if (unit > 0)*
    
  •  	{*
    
  •  		sb.Append (" and ");*
    
  •  	}*
    
  •  	sb.Append (a_Number);*
    
  •  }*
    
  •  // Return the final string*
    
  •  return sb.ToString ();*
    
  • }*
    }
    Then, to get the string from a number you just need to call the function;
    ulong number = 7653486486538954343585639u
    Debug.Log (NumberFormatter.Parse (number));

_
Parsing, good sir, is not your real problem here.
_
For games such as idle clickers, which grow their numbers in exponential manner, ulong alone is not sufficient, like, at all. Just look at it’s maximum value; it’s utterly underwhelming when compared to what you need:

const UInt64 MaxValue = 18446744073709551615;
_
This is basically 1.8 times 10 to the power of 19 which, in other words, means that the top value you can ever hope to represent here is:

18 Quintillion

Yup, that’s it, doesn’t even make past 1/4 of your ambitious list there and everything above that will be clamped to
1.8E+19
_
A solution.

To address this what you may want to do instead is to make a simple “complex” number representation of your big value. You can imagine it as Vector2, and even use this type as a substitute, but it’s x and y must mean different things in this context.

For example, this very modest little struct can hold numbers up to 3.4E+2147483685

struct MyBigNumber
{
    public float fraction;
    public int exponent;
}

To see how exactly - read BFN.cs - a full implementation example that will show you how to write algebraic operators, etc.

Well im making a Idle Clicker/Incremental game, so I figure the variables might get alittle out of hand and might be to large at some point for a reg int var to hold, so i figured i would break it down into parts so each var can get alot bigger as needed.
That Dictionary might be usefull I will look up into that see if I can implement it, def looks simpler then a zillion if statments.

I really believe the best way to get around dealing with big numbers is to never parse them at all and keep them in a string form. Then do column addition on the strings, keeping the original format, whilst still being able to carry out basic int operations. Here’s how I did it:

    public static class StringMethods
    {
        public static string Add(string str, string str2)
        {
            string combinedStr = "";

            int count = GetLargerStringCount(str, str2);
            int carry = 0;

            for (int i = count - 1; i >= 0; i--)
            {
                string I = "0";
                string J = "0";

                if (i < str.Length) { I = str*.ToString(); }*

if (i < str2.Length) { J = str2*.ToString(); }*

string combinedValue = (int.Parse(I) + int.Parse(J)).ToString();
if (combinedValue.Length > 1)
{
combinedStr += (int.Parse(combinedValue[1].ToString()) + carry).ToString();
carry = int.Parse(combinedValue[0].ToString());
}
else
{
combinedStr += (int.Parse(combinedValue[0].ToString()) + carry).ToString();
}
}

return Reverse(combinedStr);
}

static int GetLargerStringCount(string str1, string str2) =>
str1.Length > str2.Length
? str1.Length
: str2.Length;

static string Reverse(string str)
{
string reversed = “”;

for (int i = str.Length - 1; i >= 0; i–)
{
reversed += str*;*
}

return reversed;
}
}
@peacemakers1980