Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between LongInt and Integer, LongWord and Cardinal

Tags:

delphi

In Delphi, what is the difference between LongInt and Integer, LongWord and Cardinal ?

and sometimes I find the usage of DWORD, what is it?

Are they consistent in all versions of Delphi? which one should I stick to?

like image 605
justyy Avatar asked Jul 01 '14 10:07

justyy


People also ask

What is the difference between longint and cardinal and unsigned integer?

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

What is the difference between longint and Longword and integer?

In short: Longint and Longword are fixed size integers, the former signed, the latter unsigned, and both usually 32 bits in size. Their size is platform-dependent in XE8, but fixed size (32 bits) in XE7 and earlier versions. Integer and Cardinal are not fixed size.

What is the difference between long int and long int in C/C++?

Difference between long int and long long int in C/C++ S. No. Data Type Memory (bytes) Range 1 int 4 -2^15 to 2^15 – 1 2 Long int 4 -2^31 to 2^31 – 1 3 Long long int 8 -2^63 to 2^63 – 1

What is the difference between Delphi longint and Cardinal?

Delphi LongInt is the underlying platform's C++ long int. Delphi Cardinal is the underlying platform's C++ unsigned int. Delphi LongWord is the underlying platform's C++ unsigned long int. All four of these types are platform dependent. On all supported platforms at the time of writing, Integer and Cardinal are 32 bit types.


4 Answers

Short Version

| Type        | 16-bit platform | 32-bit platform | 64-bit platform  |
|-------------|-----------------|---------------- |------------------|
| Integer     | 16-bit signed   |            32-bit signed           | "generic type"
| Cardinal    | 16-bit unsigned |            32-bit unsigned         | "generic type"

| Longint     | 32-bit signed   | 32-bit signed   | 64-bit signed    | "fundamental type"
| Longword    | n/a             | 32-bit unsigned | 64-bit unsigned  | "fundamental type"
| Int64       | n/a             | 64-bit signed   | 64-bit signed    | "fundamental type"
| UInt64      | n/a             | 64-bit unsigned | 64-bit unsigned  | "fundamental type"
| Int32       | n/a             |            32-bit signed           |  
| UInt32      | n/a             |            32-bit unsigned         | 

| NativeInt   | n/a             | 32-bit signed   | 64-bit signed    |
| NativeUInt  | n/a             | 32-bit unsigned | 64-bit unsigned  |

| FixedInt    | n/a             |            32-bit signed           |
| FixedUInt   | n/a             |            32-bit unsigned         |

Long answer

We all know what they should have done:

| Type        | 16-bit platform | 32-bit platform | 64-bit platform  |
|-------------|-----------------|---------------- |------------------|
| Integer     | 16-bit signed   | 32-bit signed   | 64-bit signed    | "generic type"
| Cardinal    | 16-bit unsigned | 32-bit unsigned | 64-bit unsigned  | "generic type"

| SmallInt    |                   16-bit signed                      | "fundamental type"
| Word        |                   16-bit unsigned                    | "fundamental type"
| Longint     |                   32-bit signed                      | "fundamental type"
| Longword    |                   32-bit unsigned                    | "fundamental type"
| Int64       |                   64-bit signed                      | "fundamental type"
| UInt64      |                   64-bit unsigned                    | "fundamental type"
  • fundamental types don't change
  • generic types (aliases) do

But that's not what they did. So we are where we are.

Presumably Int32 will always be a signed 32-bit integer; but guarantees have been broken before.

Bonus Reading

  • What's New in Delphi and C++Builder XE8
  • Delphi 1 for Windows - User's Guide

Bonus Chatter

From the Delphi 5 help:

Integer types


An integer type represents a subset of the whole numbers. The generic integer types are Integer and Cardinal; use these whenever possible, since they result in the best performance for the underlying CPU and operating system. The table below gives their ranges and storage formats for the current 32-bit Object Pascal compiler.

Type      Range                    Format
--------  -----------------------  ---------------
Integer   –2147483648..2147483647  signed 32-bit
Cardinal  0..4294967295            unsigned 32-bit

Fundamental integer types include Shortint, Smallint, Longint, Int64, Byte, Word, and Longword.

Type      Range                    Format
--------  -----------------------  ----------------
Shortint  –128..127                signed 8-bit
Smallint  –32768..32767            signed 16-bit
Longint   –2147483648..2147483647  signed 32-bit
Int64     –2^63..2^63–1            signed 64-bit
Byte      0..255                   unsigned 8-bit
Word      0..65535                 unsigned 16-bit
Longword  0..4294967295            unsigned 32-bit

In general, arithmetic operations on integers return a value of type Integer—which, in its current implementation, is equivalent to the 32-bit Longint. Operations return a value of type Int64 only when performed on an Int64 operand.

Notice the "in its current implementation, is equivalent to Longint". The idea back then was that Integer would change; little did they realize that it was Longint that would change.

From the Delphi 1 User's Guide:

Data Types


Object Pascal has several data types built into the language. You can create variables of any of these predefined types. The following table lists the predefined data types:

Table 5.1 Object Pascal predefined data types

  • Integer: Numbers without a fractional part, within the range of –32768 to 32767. Requires two bytes of memory.
  • Shortint: Numbers without a fractional part, within the range of –128 to 127. Requires only one byte of memory.
  • Longint: Numbers without a fractional part, within the range of –2147483647 to 2147483647. Requires four bytes of memory.
  • Byte: Numbers without a fractional part, within the range of 0 to 255. Requires one byte of memory.
  • Word: Numbers without a fractional part, within the range of 0 to 65535. Requires two bytes of memory

From the Delphi XE6 Help:

Integer Types ================

An integer type represents a subset of the integral numbers.

Integer types can be platform-dependent and platform-independent.

Platform-Dependent Integer Types


The platform-dependent integer types are transformed to fit the bit size of the current compiler platform. The platform-dependent integer types are NativeInt and NativeUInt. Using these types whenever possible, since they result in the best performance for the underlying CPU and operating system, is desirable. The following table illustrates their ranges and storage formats for the Delphi compiler.

Platform-dependent integer types

Type         Range                    Format                                  Alias  
-----------  -----------------------  --------------------------------------  ------------
NativeInt    -2147483648..2147483647  Signed 32-bit on 32-bit platforms or    Integer
             -2^63..2^63-1            Signed 64-bit on 64-bit platforms       Int64 
NativeUInt   0..4294967295            Unsigned 32-bit on 32-bit platforms or  Cardinal
             0..2^64-1                Unsigned 64-bit on 64-bit platforms     UInt64

Platform-Independent Integer Types

Platform-independent integer types always have the same size, regardless of what platform you use. Platform-independent integer types include ShortInt, SmallInt, LongInt, Integer, Int64, Byte, Word, LongWord, Cardinal, and UInt64.

Platform-independent integer types

Type         Range                    Format           Alias  
-----------  -----------------------  ---------------  ------
ShortInt     -128..127                Signed 8-bit     Int8 
SmallInt     -32768..32767            Signed 16-bit    Int16 
LongInt      -2147483648..2147483647  Signed 32-bit    Int32 
Integer      -2147483648..2147483647  Signed 32-bit    Int32 
Int64        -2^63..2^63-1            Signed 64-bit    
Byte         0..255                   Unsigned 8-bit   UInt8 
Word         0..65535                 Unsigned 16-bit  UInt16 
LongWord     0..4294967295            Unsigned 32-bit  UInt32 
Cardinal     0..4294967295            Unsigned 32-bit  UInt32 
UInt64       0..2^64-1                Unsigned 64-bit 

Notice how Integer and Cardinal were documented as platform dependent? Also notice how LongInt and LongWord were documented as platform independent?

like image 130
Ian Boyd Avatar answered Nov 01 '22 04:11

Ian Boyd


In short: Longint and Longword are fixed size integers, the former signed, the latter unsigned, and both usually 32 bits in size. Their size is platform-dependent in XE8, but fixed size (32 bits) in XE7 and earlier versions.

Integer and Cardinal are not fixed size. They are so called "generic" integers (do not confuse this with generics, which is a different pair of shoes), i.e. they should preferrably be used when an integral type is required, regardless of the size. Depending on version and platform, the size of Integer and Cardinal may differ. Currently, they are the same size and type as Longint and Longword.

The sizes of the fixed size types don't differ between versions or platforms. You should use these types where you must interface with code or data from other sources than your own program, in other words, where exact binary compatibility is important, e.g. when calling API functions. Hence the use of types like DWORD, etc.

Note that current versions have aliases for types like Byte or Smallint. They are Int8, UInt8, Int16, UInt16, etc... up to UInt64. ISTM that these names are easier to remember than e.g. "Smallint" (16 bit signed) or "Shortint" (8 bit signed).

So use Integer and Cardinal whenever that is possible, since these are probably the ideal types for the platform and version. Use the fixed size types like Byte, Smallint, Longint or UInt64, just to name a few, when exact binary compatiblity with other data is required.

Update

Since there has been some confusion (see link near the top), and since nowadays not Longint and Longword are considered fixed size platform independent anymore, but, weirdly enough, Integer and Cardinal are considered fixed size, I more and more tend to use the (U)IntXX versions like UInt16 or Int32. One exception is my use of Byte, which I can't imagine ever changing its size (of 1).

And of course I will use Integer and Cardinal for anything that needs an integral type for which the size is not so important, e.g. for loop counters, etc.

like image 43
Rudy Velthuis Avatar answered Nov 01 '22 03:11

Rudy Velthuis


  • Delphi Integer is the underlying platform's C++ int.
  • Delphi LongInt is the underlying platform's C++ long int.
  • Delphi Cardinal is the underlying platform's C++ unsigned int.
  • Delphi LongWord is the underlying platform's C++ unsigned long int.

All four of these types are platform dependent.

On all supported platforms at the time of writing, Integer and Cardinal are 32 bit types. The types are platform dependent, it so happens that on all supported platforms the types are the same size.

On 64 bit *nix platforms, LongInt and LongWord are 64 bit types. On all other supported platforms, at the time of writing, the types are 32 bit types.

The key point is that these types are all platform dependent.

DWORD is a type alias used by the Windows API. Use it only when using that API.

Should you use Integer or LongInt? That depends on your use. As a rule, for interop use whichever type matches the C++ code. Otherwise, for most uses Integer is appropriate. Of course, this is a generic answer to your general question.

like image 30
David Heffernan Avatar answered Nov 01 '22 04:11

David Heffernan


I suggest you check Delphi documentation for best explanation: http://docwiki.embarcadero.com/RADStudio/XE5/en/Delphi_Data_Types

like image 31
SilverWarior Avatar answered Nov 01 '22 03:11

SilverWarior