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

Seems like BigInt is more about increasing the limit with the precision of an Integer, with a limit of 2^2^53, while InfiniteMath is focused on increasing the limit with precision of Floats which lets us have a much higher limit of 10^^308 (^^ = tetration).

Just depends whether you value accuracy or a higher limit more, very interesting though.

Can I trust the module for accuracy? (not precision but accuracy!). I don’t want a module that can represent up to 10^(10^308) with semantics that is not very accurate and not good.
Can I trust the module to have semantics I can predict (and anything with contrary semantic should be documented)?

Why just extend the exponent?
Are you aware you are mixing binary floating point with base-10 exponents? Why not base-2 exponents?

Did you take account of negative exponents? If not, why just positive, and is the exponent offseted by a constant (called ‘biased exponent’)?

What abstract numerical data type is this trying to represent? If it’s an abstract scalar floating point - what’s the exact precision (in bits, digits, etc) of the significand and the exact width of exponent?

Looking at the module and the source code, it doesn’t suggest that you understand floating point semantics very well. You aren’t aware that sqrt(x) and x^0.5 are different for -0.0 and -Infinity. In fact, you don’t seem to have a sufficient understanding of the concept of floor and ceil, the documentation is quite ambiguous “Rounds a number down to the nearest integer” (what does it do for negative floats?), and function named floor actually rounds towards zero (should’ve made that more clear in the documentation if that is intentional) which is in contrast to what I expect floor does given that the semantics of the floor is usually defined as rounding towards negative infinity in lots of programming language standard and in math (Floor Function – from Wolfram MathWorld). Additionally, these functions doesn’t even work for exponents >= 3 because of this if second >= 3 then return Num * sign end in the floor implementation, what’s your reason to have a guard clause of this (I don’t think it is an edge case as it checks if exponent is >= 3 which is common), and the variable name second is an odd choice)? …and this isn’t documented so I’m unsure if this is a bug or an intentional behaviour.
Also, using tostring to check for NaN (which I saw in the __eq method of InfiniteNum) isn’t a good idea nor it will be assured to work as you expect as tostring could return -nan, -nan(ind), nan(snan) etc as tostring is platform and implementation dependent, along the fact that converting a number to strings is quite an expensive process.
That’s my concern with this module.

I think metamethods are used for ergonomics purposes. Why would this be a real problem for a multi-precision library? Sure, it’s not as ergonomic.

Why would this be a deal breaker?

These instructions call functions under the hood if raw operations of these (such as number + number) aren’t available so I don’t think this brings any advantages other than ergonomics.

1 Like

A lot of what you’ve mentioned is simply just because of me lacking math skills. I made this module a few years ago with someone smarter than me to help with the math. A few months ago I told some friends about the module and my problems with it, and they decided to help improve the module.

I thought it would be a good idea to open source it, not only so people could use it, but so it could be improved as well.

Most of the accuracy issues are from me missing them, like floor rounding towards zero instead of negative infinity, I just didn’t think/didn’t know about it.

This was because I couldn’t figure out round/ceil/floor while keeping the coefficient and exponent separated (at least with usable performance), so I used the normal functions and assumed rounding after 1000 wouldn’t matter because it would be displayed with one of the notation functions (compact/scientific notation)

Before I learned the correct terms, I used first and second (first for coefficient, second for exponent), and it just never got changed.

Instead of having negative exponents, the coefficient is allowed to go between 0 and 1 for decimals when the exponent is 0. It made implementing arithmetic easier for me.

The metamethods are just there to make using this module look and feel easier. All the .add and .multiply functions will add up and it starts to get confusing, its a lot easier to just be able to use + or -. There is no real gain for this besides ease of use, and I think its important.

The module is built for games like simulators/tycoons, which normally will have a global leaderboard for players. Its important for some games, so they might prefer this module just for having that support.

This module definitely isn’t accurate in the way you describe, like you already mentioned there are multiple inaccuracies. I believe for a simulator/tycoon game, it would be accurate enough, unless there is a heavy focus on math and it being correct.

The reason I open sourced it is in the hope that people smarter than me would point these things out and maybe even fix them, and so that people who maybe don’t care about 100% accuracy could have a module with easier use (I believe) than the current alternatives.

1 Like

He just doesn’t understand the purpose of it, because he probably doesn’t play simulators or tycoons. He had similar arguments toward my post, and while I do understand his concerns, I don’t think he quite understands why we make/use these kinds of modules on Roblox.

1 Like

I think he has a few points on accuracy, but yeah it does seem like he doesn’t really understand the purpose of the module being for tycoons and simulators.

1 Like

1.3.2 is here, another small update that fixes a few things.

  • Fixed floor and ceil accuracy with negative numbers.
  • Improved the __eq nan check by removing tostring usage. nan is already stored as a string, so using tostring is pointless.
  • Fixed errors when creating a Number with -0. The created number will have a value of 0. If you need the value to be -0, please give a usage case.

Get just the module here: InfiniteMath - Roblox

1 Like

Heya, following up on this - could you publish this to Wally, as that would be useful for many people wanting to use libraries as such.

1 Like

We actually already have Wally setup!

My bad, just realized it a bit back.

I’d also like to append a feature request here: would be cool to have bitwise operator support for InfiniteMath, I can see this especially useful in cryptography.

1.3.3 is here, very small update to fix an error.

  • Fixed an error with round between 1e+100 and 1e+299

Ok should have look around a little more haha, 1.3.4 here with another tiny fix

  • Improves Reverse by removing string usage, and instead solving the scientific notation equation ({5, 7} = 5 * 10^7 = 50000000). This fixes an error with very small decimals that use e-.
1 Like

1.3.5 is here, with performance improvements thanks to Native Code Gen

  • Marks the module as native (with --!native) to increase performance.

Using this function before this update will take approx 2.6201 seconds. After this update it takes approx 1.6117 seconds (38.48% improvement). Certain functions are impacted more than others (only using new results in an 8.45% improvement)

local IM = require(game.ReplicatedStorage.InfiniteMath)

local ticker = tick()

for i = 1, 100000 do
	local Num = IM.new(i)
	
	Num *= i
	
	Num ^= i
	
	Num = IM.round(Num)
end

print(tick() - ticker)

Currently, you need to enable the Luau Native Code beta to see the effects, and live servers will not be impacted.

2 Likes