Information About Additional Integer Data Types


Description

There are several intrinsic integer datatypes. They differ by:

  • Their ability to hold negative and positive values (signed integers), or positive only (unsigned integers). The name of unsigned integer types usually begins with the letter "U"

  • The range of values they can hold, which is directly related to the number of bytes used for their storage (in memory or on disk). The storage size is traditionally expressed in bits instead of bytes (1 byte = 8 bits): 8-, 16-, 32- and 64-bits.

  • The Integer type is an alias to the platform's native signed integer type. On 32-bit builds, this ends up being Int32 and on 64-bit builds this ends up being Int64.

The default value for every Integer type is 0.

The following table summarizes these data types:

Data Type

Bytes

Range

Int8

1

-128 to 127

Int16

2

-32,768 to 32,767

Int32

4

-2,147,483,648 to 2,147,483,647

Int64

8

-2^63 to 2^63-1 (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)

UInt8 or Byte

1

0 to 255

UInt16

2

0 to 65,535

UInt32

4

0 to 4,294,967,295

UInt64

8

0 to 2^64-1 (18,446,744,073,709,551,615)

Notes

If you assign a value that is larger than what the integer type can hold, then the value will "overflow". This usually means the value will wrap around. This applies to all the data types.


Comparing signed and unsigned integer values

You should avoid comparing unsigned integer values with signed integer values as this can lead to non-obvious results for certain edge cases. In particular, literal values are always treated as Integers. Comparing a large unsigned integer to an integer literal results in the unsigned integer being converted to an Integer, which for large values can cause the sign to flip to negative, resulting in your comparison being different than you think it is.

For example:

Var value1 As UInt64 = 18446744073709551600
If value1 > 100 Then
  ' 100 is an Integer, which means that value1 is converted to an
  ' Integer for comparison. On 64-bit systems, Integer is actually
  ' Int64, and the maximum value that can hold is 9,223,372,036,854,775,807.
  ' So value1 will wrap around to be negative, its Integer value
  ' becoming -16.
  ' Since -16 is less than 100, the code does not reach this part
  ' of the If and instead falls to the Else part.
  Break
Else
  ' This is where the code execution actually ends up going.
  Break
End If

You can force the desired behavior by using CType on the literal to specifically have the compiler treat it as a UInt64. This allows the compiler to compare values of the same type, preventing any overflow issues.

Here's an example:

If value1 > CType(100, UInt64) Then
  ' Because this code forces 100 to be treated as a UInt64,
  ' both values remain as UInt64 for the purposes of comparison.
  ' Since value1 does not wrap it is still greater than 100 and the
  ' code execution goes here.
  Break
Else
  Break
End If

It is recommended that you primarily use the Integer type for your code and reserve the size-specific and unsigned types for when you need to interface with external APIs, binary data or OS calls that require integers in a specific format.

Sample code

The following declares an Int64.

Var i As Int64

This example demonstrates overflow. If you assign a number larger than 2,147,483,647 to an Int32, it will wrap around to negative values.

Var i As Int32
i = 2147483647 + 1000
' i is now -2147482649
Break

Compatibility

All project types on all supported operating systems.