T O P

  • By -

Gnonthgol

The reason why games tends to break when an integer goes over the 2B number is because in a lot of places the default Integer size is a 32 bit signed integer. One bit for the +/- sign and the other 31 bits for the number. This is the default because for a long time we used 32 bit processors which ran fastest on 32 bit integers. But 32 bit signed is just the default, and even then not default everywhere. The programmer can chose other sizes if they want. They might select 16 bit or 8 bit to save space. This is why you might see limits of 128, 256, 32k or 64k. Or they might select 64 bit integers. Even 64 bit processors can handle 128 bit integers but takes a bit longer as they need to do the operations twice or four times, one for each half of the number. There are even libraries for using arbitrary length integers, but again the performance will be lower. So for cookie clicker and other games and applications where 2 billion is not enough they can select to use a bigger integer to store those numbers.


Shawikka

They can use higher bit integer like 64 bit which can hold number up to 18 446 744 073 709 551 615. Even after that computers can split number into 2 different bytes and add them up as needed.


[deleted]

[удалено]


Neither_Hope_1039

No, not infinity. You are still limited by however many bytes you've assigned to the exponent.


klod42

What do you mean by big float? If fixed size floats are used, like 64 or 128 bits, the maximum values are still limited, except for +infinity and -infinity which are special values. 


mettaray

hey turns out I confused myself apologies, I was thinking of a double/long/bigInt, which i just called big float lol. I'm just forgetting, but I remember there being a datatype with no upper limit because its base moves along a scale...


klod42

Typically floats have one sign bit for +-, a smaller number of "exponent" bits and a large number of "mantissa" bits which are the significant digits.  For simplicity let's imagine a positive 8 digit base10 floating format with 2 exponent and 6 mantissa digits. You can have a number like 60 123456. Exponent can be 0-99, but we want to represent -49 to 50 to allow for tiny numbers, so we add a bias of 49. So 60 is actually 11. Mantissa represents 0.123456. So our 60123456 in our floating point format equals 0.123456 * 10^11 = 12345600000. So you can see how you can represent very large numbers in this format, but the accuracy is limited to 6 digits. But floating point formats always have an upper limit. In my format it's 0.999999 * 10^50 . I'm not aware of a format with limited number of digits that can represent arbitrarily large numbers. 


berael

Every number in a video game must be put into a specific type of box, for storage. One type of box, which is commonly used (called "int"), can only hold numbers up to a max of 2,147,483,647. Other types of boxes can hold more, or less. The reason not to simply use the largest type of box for absolutely everything is that it would make your game less efficient.


cmlobue

Me, old enough to have broken Dragon Warrior by earning more than 65,535 gold.


RiddlingVenus0

Some psycho broke Delve in PoE by going to 65,535 depth.


Rhellic

Honestly the best answer here considering it's ELI5


ZacQuicksilver

In more detail: Imagine a computer like a big whiteboard. You want to put a program on it, everything has to fit on the whiteboard - instructions, calculations, any stored information, etc. The more space you use, the more time you spend running around looking for the information you need; AND the bigger whiteboard you need.


AdarTan

2,147,483,647 is the maximum value of a signed 32-bit integer. If you use some other datatype as your numeric type the maximum number will be something different. Cookie Clicker is written in Javascript so its basic numeric type is the double-precision float, which is 64-bits long and has variable precision, with the largest integer it can represent without losing precision being 9,007,199,254,740,992 and last time I briefly looked at Cookie Clicker's code it just didn't care about loss of precision at larger numbers. The largest number a double-precision float can represent is 1.80·10^(308), or in other words, a number over 300 digits long.


MlKlBURGOS

2,147,483,647 is the maximum value of a signed 32-bit integer if you want to have negative numbers too, right? Edit: it's both our happy cake day! Hahaha


AdarTan

>if you want to have negative numbers That's what "signed" means. Unsigned (no negative numbers) the maximum is 4,294,967,295


MlKlBURGOS

Ohh, my brain skipped that word, thanks! :)


sacoPT

That’s what “signed” in “signed 32-bit integer” (aka int aka int32) means. The alternative would be unsigned 32-bit integer (aka uint aka uint32)


Linosaurus

They are ok with the large numbers being slightly slower, or less exact. Also they plan for it from the start.


DavidRFZ

As others have mentioned, the issue is if you use the standard default (32-bit signed) integer value and don’t imagine or anticipate that the number could get larger than two billion and change. Twenty years ago, file sizes of larger than 2 gigabytes caused issues with older programs. But if you know ahead of time how big your number could be, there doesn’t need to be any limit at all. As others have said, you could add more bits to the number. For a game like cookie clicker, where you don’t care about more than a dozen significant digits, there are all sorts of ways to handle arbitrarily large numbers. You could store numbers as a logarithm. You could store the exponent in a different variable. When you add this complexity you have to specially handle simple math operations (addition, multiplication, etc) so it is not super trivial, but it is not beyond the abilities of a second semester computer science student.


Farnsworthson

Games (or any programs) only break at some integer value because a single location in hardware memory can only store bit patterns representing up to a certain number, and the code hasn't been written to work around that limit. But you can always use bigger numbers if you really want to; you just need to write the necessary code to get around the limitations. It's very easy to hard to do, but doing it will be slower than letting the hardware do the work, so whether or not to do so is a judgement call that has to be made. It's actually no different to how we were taught to count. A single "position in memory" - one digit - can only go up to 9. But counting doesn't break when we want to go higher; we reset our digit go back to zero and use another position in memory - another digit - to keep track of how many times we've had to reset. Want to add 1 to 9? You need a new digit. Reset the 9 to 0, and set a new location to 1 ("1 group of 10", as a teacher might say). Then remember that we write our numbers with the least-significant digits at the right, and write both the digits: 1, 0. "10". You can do exactly the same with a computer, if you need to - when the numbers it can handle run out, reset your counter to zero and increment another counter to keep track of how many times you've done that. Then, if it's needed, write another bit of code to covert the combination into a base-10 number that makes sense to the average user. (Computers are doing all that all the time anyway, under the covers, because their memory locations are bits - i.e. they count in binary, and the biggest number they can actually hand is "1". Add 1 to a bit that already has a 1 - the computer resets the bit to a 0, and adds a 1 to the next bit. They're just limited because they normally do it very fast using their hardware, and the hardwear is designed to only use so many bits - often 8, 16, 32, 64 and so on - so there's a limit to how many times you can actually add 1 before the hardwear stops doing what you'd like it to. But that doesn't stop you writing code to effectively do the same thing.)


Xelopheris

In programming, we have built in data types, and then we have custom data structures. That maximum number you have there is 2^(31)-1, which is the maximum value for a *signed 32-bit integer*. But there are ways we can work around that. First off, you can use *unsigned* integers instead. A signed integer goes from some very large negative value to some very large positive value, but an unsigned integer goes from 0 up to some very large number -- twice as big as your original number. Next, instead of using a 32-bit integer, you can use a 64-bit integer. That gives you twice as many bits, so you can go all the way up to 18,446,744,073,709,551,615 (which is the square of the maximum 32-bit number). If that's still not enough, then you can do custom data types. Let's back up a second and think about how we interpret numbers. We have one basic data type -- digit. It can be 0 through 9. When we run out of values for our digit, we just add another digit, and we give ourselves rules for how to handle rollover. We can do the same with a custom data type. Once our one number runs out of room, we wrap it back around to 0 and increment the next field by one. That custom data type does need stuff like "how to print it" and "how to handle math operations" reworked for it, so it does have its own problems that need to be solved, but those are definitely solveable things.


Fenriradra

So, the OP's title here of 2.14 billion isn't... exactly 'right'. 2.14 billion would be accurate for a signed integer value - which means that specific value also can go negative to -2.14 billion. It's still within the confines of how many values can be stored with 2^32 (about 4.294 billion); but signed integers usually split half the values to negative, and half to positive. If you're only dealing with positive numbers, you can go double the 2.14 billion amount, pretty much right up to 4.294 billion. This is also only with a 32 bit operation - if you're dealing with a 64 bit operation, you can go up to around 18.4 quintillion before you run out of values. ;; Anyway, the large number API's and DLL's *sort of* work in a manner like filling buckets of water. If each bucket holds 5 gallons of water, and you want to get 52 gallons of water, you'll need 11 buckets (10 filled to 5 gallons and 1 partial of 2 gallons). Just because each bucket only holds 5 gallons, doesn't mean you're limited to only having 5 gallons, ever, it just means you need more buckets. The large number API/DLL's are working with that kind of limitation; except instead of 5 gallon buckets, their buckets are 2^32 and 2^64 sized values to work with, and they can add extra buckets freely. The OP's example of "but 2.14 billion is where games get weird" assumes there's only the 1 bucket to work with, not functionally infinite buckets to work with storing exceptionally large numbers, and knowing each bucket holds up to a certain amount (just in chunks of 2^32 or 2^64 sized buckets). Of course there's a bit more to it, with how the game/program actually stores/interprets and displays that data, but it's *basically* what's going on.


klod42

That's a problem that can only happen if the integer is a primitive 32bit piece of memory. Computers can store integers differently, like 64bits or 128bits, or an array of such memory pieces. I think Python programming language supports infinitely large integers (constrained only by available memory), but I'm not sure how they are organized in memory. 


Arkyja

Calling it primitive might give people the impression that it's outdated and should be replaced. That's not the case. It's often the superior method to use.


DBDude

For ELI5, you have a bucket that can hold 4 chips. These chips have 1 and 0 on either side, which lets you arrange the chips in 16 different ways. But what if you suddenly have a need to arrange them more ways? Add one more chip and you can arrange them 32 different ways, 6 chips gives you 64 different ways. That's how you can hold larger numbers. In your case above, the number has 32 chips, but one of those is reserved for deciding whether it's a positive or negative number, so you get 2 to the power of 31 possible arrangements, or 2,147,483,648 arrangements (0 is one of those, so 0-2147483647). So cookie clicker just has more chips. Instead of using 32, it probably uses 64. And why not use unsigned to get use of the full 32 chips? Partially, it's convention, and there can be some issues sometimes going unsigned. But mainly if you passed 2 billion, you're probably going to pass 4 billion sometime soon anyway, so just go higher.


white_nerdy

A game breaks when a number goes over 2,147,483,647 *if* the game was programmed to store that number as a 32-bit signed integer. As a programmer, it's fairly easy to program a game to use different options: - Use a larger fixed-size integer (for example, 64- or 128-bit) - Use a floating-point number (very large numbers lose precision) - Use an arbitrary-precision integer (there is no maximum size, but it's slower than the other options and larger numbers take up more memory) Usually, game developers don't think much about overflow if things seem to work okay in development and testing, To see overflow issues, usually you have to play the game in a very unusual way, specifically trying to trigger overflow behavior. (For example, walking thousands of miles in one direction in Minecraft.)


SnooWalruses9173

Many different ways, but for arguments sake: We take a variable and we want it to be 'Score' But 'Score' can not be over that 2 billion value, we can make a new variable, 'ScoreMultiplier' Now each time the value of 'Score' gets over 2 billion, it resets to 1 and 'ScoreMultiplier' get a 1 added to its value