InfiniteMath | Go above 10^308/1e+308!

InfiniteMath is a module that allows you to surpass the double-precision floating-point number limit
1 * 10^308 / 1e+308

Here is a showcase video.

Explanation.

InfiniteMath’s limit is 10^^308 / 1e+1e+308, or 1 with 10^308 zeros.

This is achieved by cleverly storing the coefficient and exponent of the number separated. If we take for example 1500, the coefficient is 1.5, and the exponent is 3.

1500 is 1.5 * 10^3, so our table will be {1.5, 3}.

We can do math with these 2 numbers always being separate, meaning we’ll never actually be storing 10^308 even if we mathematically have 10^308 or go beyond it.

InfiniteMath uses metamethods, meaning you can do arithmetic +, -, *, /, ^, % and comparison
<, >, <=, >=, ==, ~= without needing to call functions.

All you need to do is use InfiniteMath.new(num) and you’re done. You can do arithmetic with constructed numbers and normal numbers together, meaning

InfiniteMath.new(1) + 1

Will return 2.

InfiniteMath.new({1, 1000}) ^ 100

Will return 1e+100000

You can use GetSuffix() up to 1e+12000 or ScientificNotation() to format the number.

InfiniteMath.new(1000):GetSuffix()

is "1K"

But why?

You may be wondering why you would ever need to go this high with numbers? Well simulators and tycoons can benefit from this, an example being Miner’s Haven.

Miner’s Haven is a sandbox tycoon about making as much money as possible, however in end-game you can hit the number limit in a matter of minutes. Miner’s Haven would benefit greatly from increasing the number limit to further progression, which they already plan on doing themselves.

Why InfiniteMath?

Other modules exist that are capable of doing this, so why would you use InfiniteMath?

One module is OmegaNum, but the source code is an absolute mess, and doesn’t use metamethods, meaning you need to do OmegaNum.add() instead of just using +. OmegaNum does have a larger limit, but the implementation is much worse and I believe 10^^308 is enough.

Another module is EternityNum, but it doesn’t have support for OrderedDataStores, and the creator has recommended to not use it as “this one, while usable, doesn’t feel that great to use.”

Contribute and Documentation

If you want to contribute, I have a GitHub where you can make issues and pull requests. There is also a documentation website for more info.

Get it for yourself!

I have made an uncopylocked game if you would like to see how this would be used in an actual game. It’s a simple idle game with a global cash leaderboard, it’s balanced so that you can break 1e+308 in a few minutes.

You can get the module here!

If you use InfiniteMath in your game, reply with a link to your game and I’ll add it to a section of games using the module.

101 Likes

Honestly I wouldn’t use this resource because its not really for me

But it seems very impressive if the claims you said are true, I mean couldnt this be used on custom physics engine to allow it to keep being accurrate at ridiculous quantities?

9 Likes

Precision is the only downside to using something like this. Numbers are precise for 10 zeros (configurable).

If I do 1e+12 + 1 (1 Trillion + 1) nothing will happen, the number will remain exactly the same.

The more precise numbers are, the more performance it uses. 10 zeros is a good balance between precision and performance, it’s already an efficient system so performance isn’t really a worry.

There is a variable inside the module to change precision, but it will make math happen when it might barely even affect the number. Its entirely up to you how to use it though.

I think for most uses, 10 zeros is precise enough.

4 Likes

I actually use this method in my own games and raise the maximum number of a double can take. I also made a decimal version and implemented scientific, engineering and E notation converter. It was working very well with infinite bit integers. However, I left aside the performance and the operations I couldn’t seem to add to my module.

I could only make equality testing and some basic math operations including addition, subtraction, multiplication, division and other methods that could be done with these operations.

As for ordered data stores, unfortunately, I can store values up to the maximum value a double can take. Because I can’t calculate logarithm, and I need to convert the string to a number so.

3 Likes

My solution for OrderedDataStores was to convert the string into a number formatted with exponent.coefficient * 1000, so “5.5252,3” (5525.2) would turn into 355252, then save that in the datastore. Then when I get it back I divide by 1000 and reformat it back into a string. This way the number stays precise and is ordered correctly.

4 Likes

wait but if it is not precise then what is the point of this module, I mean people who make games wouldnt want wrong math calculations, I am confused

3 Likes

As soon as you start using a floating point datatype you lose some accuracy. The in built lua float is not perfectly accurate either.

5 Likes

Wait so then whats the solution for getting acurrate math operations, Do you just split the math operations into simpler ones to not be ridiculously big numbers?

4 Likes

The main thing is just being practical about it. The chances are that 10 decimal places is going to be enough for the vast majority of use cases.

Once you are aware that this is an issue it is something you can look out for. If you notice a real impact then you could start looking into arbitrary-precision datatypes. This would require a library as there isn’t an in-built lua one.

3 Likes

Thanks for your explanation, and also I just thought about it and I think even if the module is not 100% precise it is still usefull, if I had a physics engine I would rather have it become a bit inacurrate at far distances than have it not work at all (its not like I would ever have a game where I go that far from 0,0,0 anyways), and also yeah I mean if people want precise calculations for data that is delicate then modules that are slow but care about precition would be used there.

3 Likes

Sure, I’ll look into adding more math functions

1 Like

This is how pretty much all game engines work, including Roblox. Once you get too far from 0,0,0 you’ll see things jitter and deform.

5 Likes

I’ve updated the module!

  • Fixed ceil and round, now they’re identical to the original round and ceil.

  • Added sign, sqrt, fmod, and modf.

  • Fixed modulus (%). It was correct with positive numbers, but using negative numbers would return a different result than normal %.

You can get it here: InfiniteMath - Roblox

3 Likes

This looks like a really nice module. It definitely looks better than my own, which also uses metamethods. I was considering releasing my new module, but I don’t think I should anymore since there are probably enough of these modules out there at this point.

3 Likes

Thanks for the reply, I’m curious if your new module had any features or improvements InfiniteMath doesn’t have?

1 Like

Maybe just more formatting options, but I haven’t checked. My new module doesn’t use metamethods because my old module had too many issues for what I was trying to do. My new system just uses strings and functions instead, which I found to be a lot more consistent than metamethods because with metamethods, actually storing the data was quite a pain in my experiences. My newer one starts using suffixes once the exponent hits 1,000, however, which is different to when your module starts using it.

I’m not sure if your number module has some of these, but I tried to include lots of functions that also come with the math library, such as clamp, min, max, floor, etc.

My newer module also has a config which allows you to change certain bits of its behaviour:

local CONFIG = {
	ExponentToSuffix = true, -- boolean; eg 1e+1000 will be 1e+1k when using module:ToSuffix
	UseCustomFloorFunction = true, -- boolean; use custom LuaNumber round functions instead of math.floor/math.round
	RoundReplacesFloor = false, -- boolean; use math.round instead of math.floor
	DefaultSuffixDecimalPlaces = 2 -- unsigned integer (positive whole number); default amount of decimal places for module:ToSuffix to round to
}

For OrderedDataStores, your module sounds a lot more promising than mine. I’m assuming you use some sort of logarithm to compress your values so that they can fit within the 64-bit integer limit?

3 Likes

Mine includes floor round abs ceil clamp min max sign sqrt fmod and modf

I basically just do some string manipulation and a little math.

Say we have “1.2, 5” (120000), first I convert it into a number that the OrderedDataStore can use. I use the exponent as the number, with the coefficient being the decimal.

So “1.2, 5” turns into 5.12. Then because OrderedDataStores only support Integers, I multiply it as high as I want decimals, say 1000 for 4 decimal points.

So now we have 5120 which we can feed into the OrderedDataStore.

Then when we load the OrderedDataStore and get 5120 back, I divide it by 1000 to get 5.12 back, separate the number at the decimal point so I get 5, 12, then for the second number I put a decimal point after the first number in it, 12 turns into 1.2. Then I’m left with “5, 1.2”, I just flip them and I get “1.2, 5” back, our original number.

Its not super precise, but you can config how precise you want it to be, and I think you should be fine to set it pretty high.

2 Likes

Update 1.1.1 is released on the GitHub and Roblox.

  • Added 2 new notation types: Logarithm, and double letter notation.

  • Fixed a bug with IM.new() when using e+, a number like 1.1e+10 would return 1.1e+11 because it was removing the decimal point and getting 11, 10, then fixing it to 1.1, 11.

  • Increased number precision up to 16 decimal places, this is the same as normal doubles, and shouldn’t affect performance. If performance becomes and issue it can be configured. 16 is the max, as we’re still limited to normal double decimal limits.

Let me know of any suggestions you have, I’m willing to expand this module and I’m already planning on adding log and log10 functions.

4 Likes

hey i have question, example my cash is StringValue and its now 1e400 then how do i convert it into 1,400 because .new(“1e400”) doesnt work for that format string. maybe you can add a function that convert it? or make it auto converted

EDIT: i understand now its use .val

2 Likes

Great module, but I have questions

they are:

  1. why did you take the methods from math?

  2. why did you not use string interpolation everywhere?

3 Likes