Powers of Two Minus One: Difference between revisions

Expanded, added headings
m (update links)
(Expanded, added headings)
 
(3 intermediate revisions by 3 users not shown)
Line 1:
{{tropeUseful Notes}}
Video games are nothing more than computer programs, and they're limited by the systems they run on. One particularly strict limitation is the fact that computers can't handle numbers of arbitrary size with any kind of efficiency. Since efficiency is normally pretty important for video games, this places some hard limits on the range of values they can work with. Since computers work in binary, that size has to be a certain number of bits (binary digits - a zero or a one). Numbers stored in a computer's memory are called ''variables''.
 
Computers also have a limit to the maximum size a variable can be. It's not a hard limit, but using bigger numbers slows down computation considerably. Whenever you hear about the "number of bits" of a video game console (i.e. the [[Nintendo Entertainment System]] being "8-bit"), that's what they're referring to. The NES has an 8-bit data bus; it can only move 8 bits of data around at a time. If it has to move any more, it has to do it in more than one cycle. In technical terms, this is called "word size."
 
In newer video games, many things - say, the number of items in the player's [[Hyperspace Arsenal]] - are [[Cap|capped]] at reasonable limits because the variable actually used to store that value has a decidedly ''un''reasonable limit. However, in older days, it was common to let the computer itself cap these values, because the limits were a lot lower - an 8-bit computer such as the NES has a "limit" of 255.
 
The highest value you can store in a variable or register can be determined by the number of bits it uses. It's 2 to the power of the number of bits, minus 1 because we're counting from zero. Here's a handy table.
Line 11:
* '''12 bits''' can hold a value as high as 4095. Some NES games like ''[[Final Fantasy]]'' used hacks to get values this large.
* '''16 bits''' can hold a value as high as 65,535. The [[Super Nintendo Entertainment System]] and [[Sega Genesis]] were 16-bit, as were PCs in the mid 1980s, and a few Japanese gaming computers.
* '''32 bits''' can hold a value as high as 4,294,967,295. The [[Sega Saturn]] and [[Dreamcast]], Sony [[PlayStation]], Microsoft [[Xbox]] and the Nintendo [[Game Cube]] and [[Wii]] are all 32-bit. So are desktop PCs from 1987 to 2007, and Android or iOS until 2013 (iOS) or 2014 (Android), with most devices switching to 64 bit only operating systems by iOS 11 (2017), or Android 14 (2023).
* '''64 bits''' can hold a value as high as 18.4 quintillion (or 1.84×10<sup>19</sup>). The [[Nintendo 64]], Sony [[PlayStation 2]], and modern desktop PCs are all 64-bit, with 64-bit operating systems becomingbeing ratherthe commonplacedefault in 2010both (atdesktop least,and onmobile newoperating computers)systems as of 2024.
* '''128 bits''' can hold a value as high as 340.2 undecillion (or 3.4×10<sup>38</sup>). Computers usually do not have 128-bit general-purpose registers, but the [[PlayStationPlay Station 3|PS3]]'s Cell, the X-Box 360's CPU and modern x64 CPUs (used both in [[IBM Personal Computer|PCs]] and [[Apple Macintosh|Macs]]) do have 128-bit vector registers (holding 4 32-bit values). These are used for [[Vector Unit|vector math]].
 
Note that in addition to the above, most recent processors have additional "vector" processors for dealing with multiple calculations in parallel; these have so far been up to 256 bits wide. Also floating point calculations are often done at different sizes.
 
== Overflow ==
 
So what happens if you try to store a number bigger than that? Say you were trying to add one to a 16-bit variable that's already set to 65,535. It would "wrap" - adding one to 65,535 would give you zero. Adding two would give you one. And so on, and so forth. The same goes the other way - subtracting one from zero gives you 65,535. When this happens, it's called "carry" if expected or "overflow" if not. This is the source of many [[Good Bad Bugs]]; most of them are a case of programmer oversight, since the "overflow" flag in the CPU is triggered whenever this happens. Also see [[Cap]].
 
== Negative Values ==
 
However, that's not the end of the story. All of those values assume that the variable is unsigned, meaning it can't hold a negative number. Signed numbers essentially throw away one bit in order to be able to store both positive ''and'' negative numbers. Zero is taken to be the first "positive" number, while negative numbers start at -1, which makes the negative limit higher (absolutely speaking). This effectively reduces by half the maximum number that the value can hold for the sake of representing negative numbers. Here are some revised tables:
Line 27 ⟶ 31:
 
And so on.
 
== Size and Speed ==
 
It should be noted that although processors can work with variables of various sizes, they don't generally have to; a 64-bit processor can still work with 8-bit values. Thus, the limit of any given value could vary depending on the actual size of the variable used to store it. Smaller variables are often used to reduce the memory required for a game. If it's really necessary, most systems also have ways to represent numbers much ''larger'' than the hardware word size, potentially with millions of digits, but this is rarely needed in video games (and is ''significantly'' slower, too).
 
== Why gamers see these numbers ==
 
So that explains the numbers themselves. But what causes them to crop up in games? There are a few reasons these numbers show up:
Line 35 ⟶ 43:
** Note that many games exhibit bugs due to ''not'' checking the overflow after addition. That is, there's a cap because once you cross the cap, something breaks or behaves strangely.
* To use shifts. Computers can multiply and divide by powers of two by using left- and right-shift operations. Shifts are much, ''much'' faster than multiplication or division, but only work for powers of two.
** Programmers in the early days found ways around that. Want to multiply by 9? Shift left three times and add on the original number. This trick is expanded upon and used by some modern processors.
*** It might backfire on modern processors as while multiplication takes a few cycles but the shifts would introduce data hazards and cause stall cycles. Hopefully the processor will implement out-of-order execution.
* Errors. Many function calls use -1 as an error code. If this value is not checked for, and then gets stored into an unsigned variable, it becomes the highest number the variable can hold (due to how "two's complement" signing works.)
Line 44 ⟶ 52:
* Because programmers have these numbers etched into their mind-- to a sufficiently binary-minded programmer, "256" (binary 100000000) is more of a round number than "300". Hence they show up for no reason at all.
** That's a part of the reasoning for the whole concept of "magic numbers" in engineering. When you are making something you need to decide on some properties (like plank size or ceiling height, for example) anyway, so why not use the ones that someone [[Follow the Leader|has already used before]]? And then it happens that the similar sizes allow for compatibility and interoperability, it becomes a self-reinforcing convention, and we all end up with 2-by-4-s. The same logic applies to the programming too.
 
== Fractions ==
 
Now, everything thus far has been about integers. If you want to store a fractional component, you have two choices:
Line 51 ⟶ 61:
{{reflist}}
[[Category:How Video Game Specs Work]]
[[Category:Powers of Two Minus One{{PAGENAME}}]]
[[Category:Mathematics]]