Common Data Types in Free Pascal¶
Understanding Data Types¶
Every piece of data your program handles needs a type. A data type tells the compiler what kind of value you're storing—a whole number, a decimal, text, true/false, and so on. Different types use different amounts of memory and have different limitations.
Why do we need different types? Different types are designed for different purposes. A Byte uses 1 byte of memory and can store 0-255, perfect for small counts. An Integer uses 4 bytes and can store much larger numbers. If you only need to count up to 255, Byte is more efficient. For decimal numbers, you'd use Single or Double instead of integers.
Here is a reference of common data types in Free Pascal, along with simple examples you can try yourself.
See the official docs for more info; Types.
Summary Table¶
| Category | Keyword / Type | Range / Size |
|---|---|---|
| Integer | Byte |
0 .. 255 |
| Integer | ShortInt |
-128 .. 127 |
| Integer | SmallInt |
-32,768 .. 32,767 |
| Integer | Integer |
-2,147,483,648 .. 2,147,483,647 (typically 32-bit) |
| Integer | LongInt |
Same as Integer (typically 32-bit) |
| Integer | Int64 |
-9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807 (64-bit) |
| Integer | Word |
0 .. 65,535 (unsigned 16-bit) |
| Integer | Cardinal |
0 .. 4,294,967,295 (unsigned 32-bit, same as LongWord) |
| Integer | QWord |
0 .. 18,446,744,073,709,551,615 (unsigned 64-bit) |
| Boolean | Boolean |
True or False |
| Character | Char |
Single ASCII/ANSI character (or UTF-8 character element) |
| String | String |
Sequence of characters (modern FPC: typically dynamic, like AnsiString or UnicodeString) |
| Floating-Point | Single |
Approx. ±1.5 x 10^−45 .. ±3.4 x 10^38 (about 7 accurate decimal places) |
| Floating-Point | Real |
Often an alias for Double in modern FPC. Historically platform-dependent. |
| Floating-Point | Double |
Approx. ±5.0 x 10^−324 .. ±1.7 x 10^308 (about 15 accurate decimal places) |
| Floating-Point | Extended |
Higher precision than Double (platform-dependent, often 80-bit) |
| Enumerated | User-defined | A set of named constants |
| Subrange | User-defined | A specific range of an ordinal type |
| Record | record |
A collection of fields, grouping different data types |
| Advanced Record | record helper or record with methods |
Records with associated procedures and functions |
| Array | array |
Fixed-size or dynamic list of elements of the same type |
| Pointer | ^TypeName or Pointer |
Memory address of a variable or data structure |
The following examples are complete programs. You can copy, paste, and run them to see the data types in action. Remember to save files with a .pas extension.
Quick Reference: Which Type Should I Use?¶
| What you're storing | Use this type | Why |
|---|---|---|
| Small whole numbers (0-255) | Byte |
Uses less memory, fast |
| Small whole numbers (negative or positive) | ShortInt |
Uses 1 byte |
| Normal whole numbers | Integer |
Good for most situations |
| Very large whole numbers | Int64 |
Up to 9 billion and beyond |
| Decimal numbers (like 3.14) | Double |
More accurate than Single |
| Text/words | String |
Can store any text |
| True or false only | Boolean |
For yes/no decisions |
Integer Types¶
What are integers? Integers are whole numbers without decimals (like 5, -10, 1000). Different integer types can store different ranges of numbers and use different amounts of memory.
A note about "accurate decimal places": When we say Single has "7 accurate decimal places," it means if you store a number like 3.1415926, you can reliably trust the first 7 digits. The 8th digit and beyond might not be exact. Double is more precise—it can reliably store about 15 decimal places.
Byte¶
- Range: 0 .. 255 (unsigned, meaning no negative numbers)
- When to use: Ages, test scores (0-100), array indices, or any small positive count
- Memory: 1 byte
- Example:
ShortInt¶
- Range: -128 .. 127 (signed, can be negative or positive)
- When to use: Temperature readings, altitude differences, or small numbers that might be negative
- Memory: 1 byte
- Example:
SmallInt¶
- Range: -32,768 .. 32,767
- Example:
Integer¶
- Range: Typically -2,147,483,648 .. 2,147,483,647 (32-bit signed)
- When to use: Most everyday counting (user IDs, scores, populations). This is the "default" integer type and a good choice when you're unsure
- Memory: 4 bytes
- Example:
LongInt¶
- Range: Same as
Integer(typically 32-bit signed) - Example:
Int64¶
- Range: -9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807 (64-bit signed—huge numbers!)
- When to use: Very large numbers like national populations, file sizes in bytes, or milliseconds since a date
- Memory: 8 bytes
- Example:
Word¶
- Range: 0 .. 65,535 (16-bit unsigned)
- Example:
Cardinal¶
- Range: 0 .. 4,294,967,295 (32-bit unsigned, same as
LongWord) - Example:
QWord¶
- Range: 0 .. 18,446,744,073,709,551,615 (64-bit unsigned)
- Example:
Boolean¶
- Values:
TrueorFalse - Example:
Char (Character)¶
- Range: Typically a single ASCII or ANSI character. In UTF-8 mode, it can be one byte of a multi-byte character.
- Example:
String¶
- Description: A sequence of characters (text). In modern Free Pascal,
Stringis dynamic, meaning it grows and shrinks as needed. You can store "Hi" or "This is a very long sentence" in the same variable. - ShortString (old style): You might see
String[50]in old code—this is a ShortString with a maximum of 50 characters. Avoid this in new code; use plainStringinstead. - When to use: Storing names, messages, user input—basically any text data
- Memory: Dynamic (grows as needed)
- Example:
Floating-Point Types¶
What are floating-point numbers? These are numbers with decimals (like 3.14, -0.5, or 2.718). They're called "floating-point" because the decimal point can "float" to different positions. Important note: floating-point numbers are approximations, not exact values. Don't use them for money calculations unless you know what you're doing!
Single¶
- Range: Approximately ±1.5 x 10^−45 .. ±3.4 x 10^38
- Precision: About 7 accurate decimal places (e.g., 3.141592 is reliable, but the 8th digit might be wrong)
- When to use: Graphics, physics simulations, or when memory matters more than perfect accuracy
- Memory: 4 bytes
- Example:
Real¶
- Description: In modern Free Pascal,
Realis often an alias forDouble. Historically, its size and precision were platform-dependent. - Example:
Double¶
- Range: Approximately ±5.0 x 10^−324 .. ±1.7 x 10^308
- Precision: About 15 accurate decimal places (much better than
Single) - When to use: Science, engineering, or any calculation where accuracy matters.
Doubleis usually the best choice for decimal numbers - Memory: 8 bytes
- Example:
Extended¶
- Description: Offers higher precision than
Double. Its exact size is platform-dependent (often 80-bit on x86 systems). Use only if you need extreme precision. - When to use: Advanced scientific calculations requiring extreme precision
- Memory: Platform-dependent (typically 10 bytes)
- Example:
Enumerated Types¶
- Description: A type where you define a set of named values. Internally, these are represented by integers (0, 1, 2,...).
- When to use: When you have a fixed list of options (like colors, days of the week, or game states). Much clearer than using magic numbers!
- Example use case: Instead of storing day as 1, 2, 3... (confusing), use an enum with names: Monday, Tuesday, Wednesday (clear and self-documenting)
- Example:
Subrange Types¶
- Description: A type that represents a subset of values from another ordinal type (like Integer or Char). For example, instead of allowing any Integer (which includes negatives), you might define a type that only allows 0-100.
- When to use: When you want to limit a variable to a specific range. The compiler can catch errors if you try to assign invalid values!
- Example use cases:
- Test scores: 0..100 (not negative, not over 100)
- Month numbers: 1..12 (only 12 months)
- Grade letters: 'A'..'F' (only uppercase letters A through F)
- Example:
Record Types¶
- Description: A composite data type that groups together variables (fields) of different types under a single name.
- Example:
Advanced Records (with methods)¶
- Description: Records in modern Object Pascal can also have methods (procedures and functions) associated with them, similar to objects.
- Note: Advanced records require a special compiler directive to work (see below).
- Example:
Arrays¶
Static Array¶
- Description: An array with a fixed size determined at compile time.
- Example:
Dynamic Array¶
- Description: An array whose size can be changed at runtime using
SetLength. Dynamic arrays are 0-indexed. - Example:
Pointers¶
⚠️ Advanced Topic
Pointers are an advanced feature. If you're new to programming, skip this section for now and come back to it later. Most modern code avoids pointers when possible—use dynamic arrays and classes instead.
- Description: A pointer holds the memory address of a variable. They are used for dynamic memory allocation and low-level programming.
^TypeNamedeclares a pointer toTypeName.Pointeris a generic pointer type. - When to use: Only when you need direct memory access or working with C libraries. Beginners should avoid!
- Example: