How to use numbers greater than 2^53

money = 123456789012345678 --Read 123 456 789 012 345 6 78 (no spaces) print(string.format('%.f',money)) --\> Displays 1234567890123456 80 -- notice last two digits

The problem is after 16 digits. The stored value of money would be different than the one displayed

on screen to the player.

Actually this can be done but the problem would come when displaying those values to the player.

The way floating point works, the range spreads out more and more as you go up past successive powers of 2. After 2^53, you can only represent 1 / 2^53 of the range from 2^53 to 2^54, which is only enough to hit even integers (and no fractional values in between), but you’d already be down to 64ths of an integer around 2^45. (Some of this might be off by one, but the point stands.) This is also why you have such fantastic accuracy from -1 to 1, along with denormals.

This actually is important in financial transactions and various formats like binary-coded decimal have been introduced as alternatives to the more scientist- and engineer-oriented floating points.

I think you’d be fine adopting something like nick_sherman suggests. If you need to multiply just break it down like you’d do it by hand. Displaying shouldn’t be an issue; just build the string up.

I need to use values much greater than trillions.

My game is a clicker, so I have a few autoclickers in my game which buy/sell items and deduct/add changes to the player money variable which is then displayed on screen. 

The only problem is that the money variable would differ from what is presented to the player and some other issues while doing

arithmetic.

I was talking of this kind of string function: 

> = string.sub(“Hello Lua user”, 7) – from character 7 until the end
Lua user
> = string.sub(“Hello Lua user”, 7, 9) – from character 7 until and including 9
Lua
> = string.sub(“Hello Lua user”, -8) – 8 from the end until the end
Lua user
> = string.sub(“Hello Lua user”, -8, 9) – 8 from the end until 9 from the start
Lua
> = string.sub(“Hello Lua user”, -8, -6) – 8 from the end until 6 from the end 

Like this you have your number in one unique value and you need a little operation to update it or compare it

Don’t use string format, just do:

[lua]

print (Quadrillions…","…Trillions…","…Billions…","…Millions…","…Balance)

[/lua]

Although you’d need a function to add a comma to Balance.

Yeah displaying would not be an issue but I am not sure about arithmetic like when buying items or selling items etc.

Items will also have their values stored like this. Add/Subtract the values from each unit to/from each other. 

If adding, work from Balance to Quadrillions, checking if there is an overflow and if so adding to the next unit and subtracting from the current one. If subtracting, work the opposite way round.

Ohh… this can work I didnt came across it earlier. Will surely try it. :slight_smile:

Yes I could do that.

Btw Lua has an example function called comma_value to add commas after thousands. I would need to modify that function.

The function is ->

function comma\_value(amount) local formatted = string.format('%.f',amount) while true do formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') if (k==0) then break end end return formatted end

Thank you guys, I will try implementing both  nick_sherman and

remiduchalard’s  approaches. 

Hey guys.  This is a fascinating discussion.

When an answer is arrived at that works, would someone please post the code back here?

I think a working solution that folks could study and run would really be the cherry on top of this sweet discussion.

Yes I will post the code when I find the best solution.

But just off my head I think nick_sherman method might be better because it would be much easier to implement.

Any update on this? I currently have a clicker/incremental game that’s been out for a while, and I’m slowly approaching the number limit. Looking for a drop in solution to extend the current way numbers are handled and “just work” like numbers usually would.

If you think you can do this, I’m willing to pay $$$ for a drop in solution. You can PM me if you’d like to talk in private.

Thanks!

Hello @naveen_pcs

There is many solution, I have write down one but without testing.

local myMonney="10000000000" -- I assume all number began by not a 0 local function myStringNumbertoNumber(myNumber) local theNumber={} local i=0 while(i\*30\<string.len(myNumber)) do theNumber[i]=tonumber(string.sub(myNumber,i\*30,(i+1)\*30)) i=i+1 end return theNumber end local function myNumberToMyString(myNumber) local theNumber="" for(i=0,#myNumber)do theNumber=theNumber..myNumber[i] end return theNumber end local function compareLargeNumber(myNumber,myMonney) local theMyNumber=myStringNumbertoNumber(myNumber) local theMyMonney=myStringNumbertoNumber(myMonney) local result=0 -- 0 for equal, 1 for \>,2 for \< if(#theMyNumber\>#theMyMonney) then result=1 else if(#theMyNumber\<#theMyMonney) then result=2 else local i=0 while(i\<#theMyMonney) do if(theMyNumber[i]\>theMyMonney[i])then result=1 i=100 -- large number else if(theMyNumber[i]\<theMyMonney[i])then result=2 i=100 --large number else i=i+1 end end end return result end local function addOrMinus(myNumber,myMonney,addOrMinus)--addOrMinus is true for add and false to minus local theMyNumber=myStringNumbertoNumber(myNumber) local theMyMonney=myStringNumbertoNumber(myMonney) -- continue like this, I think you have understood the logic behind end

In my game. But lua looses precision after numbers greater than 2^53.

It’s not Lua at fault, it’s IEEE754 doubles.

But what’s the real issue - just output fomatting or actual internal precision?

I’ll tell you that the vast majority of incremental games out there (including ones that I’ve worked on) just use IEEE754 doubles and get away with it just fine.  Because they’re NOT trying to add 1 to 1E33, for example.

That is, it’s the nature of the game that in order to get a ridiculously large “bank”, you need correspondingly ridiculously large “producers”.  So all the math is always happening “within range” of what double precision is capable of.

Yes, you’d start losing “pennies” eventually, as you run out of bits to represent them, but who cares?! Most of these games, once beyond a certain point (usually about 1e9) start using some sort of modified scientific notation and maybe give you four or five decimals at most (fe 1.2345De for decillions, rarely would you see all 33 digits printed)

Consider:  If your balance is in the 1e33 range, and you THINK you need to be worried about some “producer” making $1/second, … it would take something like 1e12 years before it even affected the 15th decimal place!  Few of your players will live that long.

(As nick sherman said) How about using a table like so: 

local money = {ones=0, hundreds=0, thousands=0, millions=0, billions=0, trillions=0, quadrillions=0}

Then you only need a string building function to parse the table and print the proper 0’s and commas.

If only someone had already suggested that :wink:

Whoops sorry. You did already suggest that.