Integer: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Integer
| Old | New | Line | |
|---|---|---|---|
| 1 | + | The [[Data type|data type]] `integer` is a [[Standard type|built-in]] data type of the programming language [[Pascal]]. It can store a subset of ℤ, the set of whole numbers. | |
| 2 | + | ||
| 3 | + | ## `integer` literal | |
| 4 | + | ||
| 5 | + | ### basics | |
| 6 | + | ||
| 7 | + | An `integer` is specified as a non-empty series of consecutive Western-Arabic digits. | |
| 8 | + | ||
| 9 | + | ``` pascal | |
| 10 | + | 1234 | |
| 11 | + | ``` | |
| 12 | + | ||
| 13 | + | The value of `1234` is $`1 \times 10^3 + 2 \times 10^2 + 3 \times 10^1 + 4 \times 10^0`$. The `integer` may be preceded by a sign, [[Plus|+]] or [[Minus|−]], even if *mathematically speaking* the value is signless (this concerns the value zero). | |
| 14 | + | ||
| 15 | + | ``` pascal | |
| 16 | + | +0 { ✔ syntactically correct } | |
| 17 | + | ``` | |
| 18 | + | ||
| 19 | + | If no sign is specified, a positive sign is presumed. | |
| 20 | + | ||
| 21 | + | In Free Pascal, you can use the [[Underscore|underscore]] to group digits if `{$modeSwitch underscoreIsSeparator+}` (as of 2022 only [[FPC New Features Trunk|available in trunk]]). | |
| 22 | + | ||
| 23 | + | ```delphi | |
| 24 | + | 1_000_000_000 | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | ### varying base | |
| 28 | + | ||
| 29 | + | To change the base in [[Extended Pascal]] you prefix the `integer` literal with a base specification: | |
| 30 | + | ||
| 31 | + | ``` pascal | |
| 32 | + | 8#1234 | |
| 33 | + | ``` | |
| 34 | + | ||
| 35 | + | This represents the value $`1 \times 8^3 + 2 \times 8^2 + 3 \times 8^1 + 4 \times 8^0`$. The base can be any value between `2` and `36` (inclusive) and can *only* be specified to a *decimal* base. A base specification possibly extends or restricts the set of allowed digits to those in the set of `0` to `base − 1` from below table: | |
| 36 | + | ||
| 37 | + | | digit (case-insensitive) | `0` | `1` | `2` | `3` | `4` | `5` | `6` | `7` | `8` | `9` | `A` | `B` | | |
| 38 | + | |----|----|----|----|----|----|----|----|----|----|----|----|----| | |
| 39 | + | | value (decimal) | $`0`$ | $`1`$ | $`2`$ | $`3`$ | $`4`$ | $`5`$ | $`6`$ | $`7`$ | $`8`$ | $`9`$ | $`10`$ | $`11`$ | | |
| 40 | + | | digit (case-insensitive) | `C` | `D` | `E` | `F` | `G` | `H` | `I` | `J` | `K` | `L` | `M` | `N` | | |
| 41 | + | | value (decimal) | $`12`$ | $`13`$ | $`14`$ | $`15`$ | $`16`$ | $`17`$ | $`18`$ | $`19`$ | $`20`$ | $`21`$ | $`22`$ | $`23`$ | | |
| 42 | + | | digit (case-insensitive) | `O` | `P` | `Q` | `R` | `S` | `T` | `U` | `V` | `W` | `X` | `Y` | `Z` | | |
| 43 | + | | value (decimal) | $`24`$ | $`25`$ | $`26`$ | $`27`$ | $`28`$ | $`29`$ | $`30`$ | $`31`$ | $`32`$ | $`33`$ | $`34`$ | $`35`$ | | |
| 44 | + | ||
| 45 | + | `integer` digits in Extended Pascal | |
| 46 | + | ||
| 47 | + | As of version 3.2.0, the [[FPC]] intends to ([[Mode extendedpascal|{$mode extendedPascal}]]), but does not yet support a generic base-specification format. Instead only the following bases are recognized: | |
| 48 | + | ||
| 49 | + | | base | indicator | sample (decimal value) | | |
| 50 | + | |----|----|----| | |
| 51 | + | | [[Binary numeral system|binary]] ($`2`$) | [[Percent sign|%]] | `%1010` ($`10`$) | | |
| 52 | + | | octal ($`8`$) | [[&]] | `&644` ($`420`$) | | |
| 53 | + | | decimal ($`10`$) | *none* | `1337` ($`1337`$) | | |
| 54 | + | | [[Hexadecimal|hexadecimal]] ($`16`$) | [[Dollar sign|$]] | `$2A` ($`42`$) | | |
| 55 | + | ||
| 56 | + | `integer` base specifications in FPC 3.2.0 | |
| 57 | + | ||
| 58 | + | ## characteristics | |
| 59 | + | ||
| 60 | + | It is guaranteed that all arithmetic operations in the range [[maxint|−maxInt..+maxInt]] work accurately. An `integer` [[Variable|variable]] *may* possibly store values *beyond* this range, but once you leave this range it is *not guaranteed* anymore that arithmetic operations work correctly. Textbook example: | |
| 61 | + | ||
| 62 | + | ``` pascal | |
| 63 | + | program lordOverflowStrikesAgain(output); | |
| 64 | + | {$overflowChecks on} | |
| 65 | + | var | |
| 66 | + | x: integer; | |
| 67 | + | begin | |
| 68 | + | x := -maxInt; | |
| 69 | + | x := pred(x); { If this doesn’t cause an error, `-maxInt - 1` storable. } | |
| 70 | + | writeLn(abs(x)); | |
| 71 | + | end. | |
| 72 | + | ``` | |
| 73 | + | ||
| 74 | + | Depending on the processor used, this *may* print: | |
| 75 | + | ||
| 76 | + | ```text | |
| 77 | + | -9223372036854775808 | |
| 78 | + | ``` | |
| 79 | + | ||
| 80 | + | A quite unexpected result since [[Abs|abs]] should in principle return a *non-negative* value, yet *expectable* since `pred(−maxInt)` is evidently not in the `−maxInt..+maxInt` range. | |
| 81 | + | ||
| 82 | + | ## application | |
| 83 | + | ||
| 84 | + | `Integer` is the data of choice if arithmetic results have to be *precise*. The data type [[Real|real]] may provide “reasonable approximations”, but operations on `integer` have to be exact (only guaranteed as long as it is in the `−maxInt..+maxInt` range). Generally speaking `integer` operations are also *faster* than if done in the domain of `real`. | |
| 85 | + | ||
| 86 | + | The operators [[Div|div]] and [[Mod|mod]] only work on `integer` values (the `math` `unit` provides the [`fMod` `function`](https://www.freepascal.org/docs-html/rtl/math/fmod.html) and [[Operator overloading|overloads]] `mod`). | |
| 87 | + | ||
| 88 | + | ## Free Pascal deviations | |
| 89 | + | ||
| 90 | + | The FPC does not have *a single* data type `integer` but a host of `integer` data types. An `integer` literal such as `123` possesses the data type of closest fitting range from the following table. | |
| 91 | + | ||
| 92 | + | | name (aliases) | smallest storable value | largest storable value | [[SizeOf|sizeOf]] | | |
| 93 | + | |----|----|----|----| | |
| 94 | + | | [`shortInt`](https://www.freepascal.org/docs-html/rtl/system/shortint.html) ([`int8`](https://www.freepascal.org/docs-html/rtl/system/int8.html)) | `-128` ($`-2^7`$) | `127` ($`2^7-1`$) | 1 | | |
| 95 | + | | [`byte`](https://www.freepascal.org/docs-html/rtl/system/byte.html) ([`uInt8`](https://www.freepascal.org/docs-html/rtl/system/uint8.html)) | `0` ($`0`$) | `255` ($`2^8-1`$) | 1 | | |
| 96 | + | | [`smallInt`](https://www.freepascal.org/docs-html/rtl/system/smallint.html) ([`int16`](https://www.freepascal.org/docs-html/rtl/system/int16.html)) | `-32768` ($`-2^{15}`$) | `32767` ($`2^{15}-1`$) | 2 | | |
| 97 | + | | [[Word|word]] ([`uInt16`](https://www.freepascal.org/docs-html/rtl/system/uint16.html)) | `0` ($`0`$) | `65535` ($`2^{16}-1`$) | 2 | | |
| 98 | + | | [`longInt`](https://www.freepascal.org/docs-html/rtl/system/longint.html) ([`int32`](https://www.freepascal.org/docs-html/rtl/system/int32.html)) | `-2147483648` ($`-2^{31}`$) | `2147483647` ($`2^{31}-1`$) | 4 | | |
| 99 | + | | [`longWord`](https://www.freepascal.org/docs-html/rtl/system/longword.html) ([`cardinal`](https://www.freepascal.org/docs-html/rtl/system/cardinal.html), [`dWord`](https://www.freepascal.org/docs-html/rtl/system/dword.html)) | `0` ($`0`$) | `4294967295` ($`2^{32}-1`$) | 4 | | |
| 100 | + | | [`int64`](https://www.freepascal.org/docs-html/rtl/system/int64.html) | `-9223372036854775808` ($`-2^{63}`$) | `9223372036854775807` ($`2^{63}-1`$) | 8 | | |
| 101 | + | | [`qWord`](https://www.freepascal.org/docs-html/rtl/system/qword.html) ([`uInt64`](https://www.freepascal.org/docs-html/rtl/system/uint64.html)) | `0` ($`0`$) | `18446744073709551615` ($`2^{64}-1`$) | 8 | | |
| 102 | + | ||
| 103 | + | integer data types in FPC version 3.2.0 | |
| 104 | + | ||
| 105 | + | The signed ranges are preferred (i. e. as in the top/down order in the table), thus `123` possesses the data type `shortInt` even though it could be a `byte`, too. | |
| 106 | + | ||
| 107 | + | As of version 3.2.0, the data type [`integer`](https://www.freepascal.org/docs-html/rtl/system/integer.html) is simply an alias depending on the currently selected [[Compiler Mode|compiler compatibility mode]]. It does *not* depend on the CPU type, therefore it is quite possible that the CPU could in fact deal with integers having an even larger magnitude than `integer` provides. | |
| 108 | + | ||
| 109 | + | | mode | `integer` is an alias for | value of `maxInt` | | |
| 110 | + | |----|----|----| | |
| 111 | + | | [[Mode FPC|{$mode FPC}]], [[Mode MacPas|{$mode macPas}]] and [[Mode TP|{$mode TP}]] | `smallInt` | `32767` | | |
| 112 | + | | *all other available modes* | `longInt` | `2147483647` | | |
| 113 | + | ||
| 114 | + | the data type `integer` in FPC version 3.2.0 | |
| 115 | + | ||
| 116 | + | > **Warning:** Undocumented feature: General programming advice, do not use what has not been documented. Unlikely as it may be, the following feature may be removed at any time. | |
| 117 | + | ||
| 118 | + | Depending on the [[Platform defines|platform’s]] arithmetic logic unit’s word size (ALU) following [aliases are available](https://gitlab.com/freepascal.org/source/fpc/release_3_2_0/rtl/inc/systemh.inc#L390-L412). | |
| 119 | + | ||
| 120 | + | ```delphi | |
| 121 | + | type | |
| 122 | + | {$ifDef CPU16} ALUSInt = smallInt; ALUUInt = word; {$endIf} | |
| 123 | + | {$ifDef CPU32} ALUSInt = longInt; ALUUInt = dWord; {$endIf} | |
| 124 | + | {$ifDef CPU64} ALUSInt = int64; ALUUInt = qWord; {$endIf} | |
| 125 | + | ``` | |
| 126 | + | ||
| 127 | + | Although it is frequently the case that the ALU’s word size also coincides with the size of a pointer, it is not guaranteed (e. g. the x32-ABI uses 64‑bit ALU, but only 32‑bit pointers). Therefore if an `integer` value is meant to be [[Typecast|typecasted]] to a [[Pointer|pointer]], it recommended to use [`ptrUInt`](https://www.freepascal.org/docs-html/rtl/system/ptruint.html). Note, the data type [`nativeInt`](https://www.freepascal.org/docs-html/rtl/system/nativeint.html) is in fact an alias for [[PtrInt|ptrInt]] and [not related to `ALUSInt`](https://gitlab.com/freepascal.org/fpc/source/-/tree/release_3_2_0/rtl/inc/systemh.inc#L414-422). | |
| 128 | + | ||
| 129 | + | ## see also | |
| 130 | + | ||
| 131 | + | - [[Real|real]], the data type used to store/process (a subset of) rational numbers | |
| 132 | + | - [[gmp|GNU Multiple Precision Arithmetic Library]], precise mathematical operations on arbitrarily large values \[if 8-Byte `int64`/`qWord` are not enough\] | |
| 133 | + | ||
| 134 | + | --- | |
| 135 | + | *From the Free Pascal wiki, page "Integer", as it stood on 2024-04-05 after a change by Mischi, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
