Integer Data Types in Delphi


The basic integer type in 16-bit Turbo Pascal is 16-bit while from 32-bit Delphi, it is 32-bit. The basic integer types for modern Delphi compilers are: byte, ShortInt, Word, SmallInt, LongWord, Cardinal, LongInt, Integer and Int64. The following shows their data ranges so you know weather they are signed or unsigned.

var
   // Integer data types :
   Int1 : Byte;     //                        0 to 255
   Int2 : ShortInt; //                     -127 to 127
   Int3 : Word;     //                        0 to 65,535
   Int4 : SmallInt; //                  -32,768 to 32,767
   Int5 : LongWord; //                        0 to 4,294,967,295
   Int6 : Cardinal; //                        0 to 4,294,967,295
   Int7 : LongInt;  //           -2,147,483,648 to 2,147,483,647
   Int8 : Integer;  //           -2,147,483,648 to 2,147,483,647
   Int9 : Int64;  // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
   Int0:  UInt64;  // 0 to 2^64 - 1

The Byte and ShortInt consumes only 8-bit (one single byte). The Word and SmallInt are 2 bytes. The LongWord, Cardinal, LongInt and Integer are 4 bytes and Int64 and UInt64 as their name imply, are 8 bytes (64-bit).

The Byte, Word, LongWord, UInt64, and Cardinal are unsigned while ShortInt, SmallInt, LongInt, Integer and Int64 are signed (the left most bit denotes the sign bit).

It is also worth to note that, the NativeInt (signed) and NativeUInt (unsigned) are two integer types that are platform dependent. They are supposed to be the size of the pointers e.g. On 32-bit, the pointer size is 4 bytes and on 64-bit the pointer size is 8 bytes. However, the implementation of NativeInt and NativeUInt are buggy until Delphi 2009. The sizes are incorrectly set before D2009.

TYPE Delphi Version Size
NativeInt D5 N/A
NativeInt D6 N/A
NativeInt D7 8 bytes
NativeInt D2005 8 bytes
NativeInt D2006 8 bytes
NativeInt D2007 8 bytes
NativeInt D2009 4 bytes
NativeInt D2010 4 bytes
NativeInt Delphi XE 4 bytes
NativeInt Delphi XE2 4 or 8 bytes

To sum up,

Type Description Pointer
Byte 8-bit unsigned integer PByte
ShortInt 8-bit signed integer PShortInt
Word 16-bit unsigned integer PWord
SmallInt 16-bit signed integer PSmallInt
Cardinal 32-bit unsigned integer PCardinal
LongWord 32-bit unsigned integer PLongWord
Integer 32-bit signed integer PInteger
LongInt 32-bit signed integer PLongint
UInt64 64-bit unsigned integer PUInt64
Int64 64-bit signed integer PInt64
NativeUInt 64-bit or 32-bit platform-dependent unsigned integer PNativeUInt
NativeInt 64-bit or 32-bit platform-dependent signed integer PNativeInt

The pointer type for each integer is just simply with a prefix ‘P’ and its declaration is like this:

Type 
    PInteger = ^Integer;

There are aliases. Integer is a 32-bit signed integer type – Longint is an alias for this type. Cardinal is a 32-bit unsigned integer type – LongWord is an alias for this type.

And sometimes, you will notice in Windows unit, there is a 32-bit type alias DWORD (Double Word) which is defined as LongWord. Mainly, it is for Win32 APIs.

Also, on windows, WPARAM is unsigned and LPARAM is signed integer. They are defined in Windows unit as follows.

  UIntPtr = NativeUInt;
  UINT_PTR = System.UIntPtr;
  WPARAM = UINT_PTR;

  LPARAM = INT_PTR;
  INT_PTR = System.IntPtr;
  IntPtr  = NativeInt;

And to gain more code readability, you could use the following defined types in System Unit.

  Int8    = ShortInt;
  Int16   = SmallInt;
  Int32   = Integer;
  IntPtr  = NativeInt;
  UInt8   = Byte;
  UInt16  = Word;
  UInt32  = Cardinal;
  UIntPtr = NativeUInt;

As said, the Integer and Cardinal changed in the past, from D1 to D2 and (from 16-bit TP and Delphi to 32 bit). So it is unknown that in the future they will change or not.

In pointer arithmetic, use PByte or PAnsiChar instead of NativeInt and NativeUInt (read more here)

Also, if would be nice to have some declaration like this (e.g. FastMM4 memory manager) (to be included at the very beginning of your project dpr file).

{----------------------------Public types------------------------------}
type
  {Make sure all the required types are available}
{$ifdef BCB6OrDelphi6AndUp} // (Borland C++ Builder 6 or Delphi 6) or later
  {$if CompilerVersion < 20}
  PByte = PAnsiChar;
  {NativeInt didn't exist or was broken before Delphi 2009.}
  NativeInt = Integer;
  {$ifend}
  {$if CompilerVersion < 21}
  {NativeUInt didn't exist or was broken before Delphi 2010.}
  NativeUInt = Cardinal;
  {$ifend}
  {$if CompilerVersion < 22}
  {PNativeUInt didn't exist before Delphi XE.}
  PNativeUInt = ^Cardinal;
  {$ifend}
  {$if CompilerVersion < 23}
  {IntPtr and UIntPtr didn't exist before Delphi XE2.}
  IntPtr = Integer;
  UIntPtr = Cardinal;
  {$ifend}
{$else}
  PByte = PAnsiChar;
  NativeInt = Integer;
  NativeUInt = Cardinal;
  PNativeUInt = ^Cardinal;
  IntPtr = Integer;
  UIntPtr = Cardinal;
{$endif}

References

[1] http://stackoverflow.com/questions/24507704/difference-between-longint-and-integer-longword-and-cardinal

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
1489 words
Last Post: Reverse String in C/C++ (String Reversal Algorithm)
Next Post: How to Match Word Boundary using SQL?

The Permanent URL is: Integer Data Types in Delphi

Leave a Reply