GOOC - Game Oriented Object C

GOOC - Game Oriented Object C

Next: Expressions and Operators, Previous: Lexer Tokens, Up: Top
[Contents]

6. Integers & Fixed-Point Arithmetic

6. Integers & Fixed-Point Arithmetic

There is only one distinct data type in GOOC: the 32-bit integer, can hold any whole number from -2,147,483,648 to 2,147,483,647. Any numbered value, be it a pointer, instruction offset, or animation offset, is converted into an integer of this type at some point during program execution. Even though the underlying type is a signed integer, the parser allows for any 32-bit unsigned integer as well. The value 4,294,967,295 for example, will be parsed correctly as 0xFFFFFFFF, but the actual value the parser will use is -1.

Even though only one data type is ever used, this integer can be interpreted in various different ways. The base number unit in the games is a Q8 fixed point value, meaning the lower 8 bits of the 32-bit integer are used to define the fractional part and the upper 24 bits to define the whole part. Thus, one game unit is equivalent to the integer "256". Since all operations, both in the GOOC program and the game, use the integer type, extra care should be taken in regards to precision and overflow prevention when doing operations such as multiplication and division.

For example, if two Q8 fixed point numbers are multiplied together, the result will be a 16-bit fixed point value (8 + 8), which is 8 bits higher than expected, if we want our result to be in the base unit type (which has 8 bits of fractional part), the result needs to be right-shift by 8 bits: INCORRECT: 1.0 * 1.0 = 256 * 256 = 65536 = 256.0 CORRECT: 1.0 * 1.0 >> 8 = 256 * 256 >> 8 = 65536 >> 8 = 256 = 1.0 Note that the result before right-shifting the result of the multiplication was very large. Multiplying fixed point values can greatly increase the chance of overflowing the result if proper care isn't taken. This will usually not be too big of an issue, but is worth keeping in mind nonetheless.

Dividing fixed point works in mostly the opposite way of multiplying them. Dividing two 8-bit fixed point values results in a quocient with precision 0 (8 - 8), meaning there is no fractional part at all. To solve this, we left shift the dividend by however many bits of precision we want (8 in the case of wanting the result in the base unit type): INCORRECT: 50.0 / 100.0 = 12800 / 25600 = 0 CORRECT: (50.0 << 8) / 100.0 = 3276800 / 25600 = 128 = 0.5

EIDs, while stored as integers, cannot be used in any sort of arithmetic or other mathematical operation, due to their mutability. You will get a compiler error if you try to use one. They are also not permitted in arrays.