VB8(VB2005)以降では符号なし整数型を使うことができます。 ULongは64ビット、UIntegerは32ビット、UShortは16ビットの符号なし整数です。 VB7以前から存在した8ビットの符号なし整数Byteも引き続き使えます。

§1 ULong・UInteger・UShort

符号付き整数型のLongIntegerShortに対応する符号なし(Unsigned)整数型はそれぞれULongUIntegerUShortとなります。 8ビットの符号なし整数型Byteに対応する符号付き(Signed)整数型はSByteとなります。 対応関係は次のとおりです。

符号付き・符号なしの整数型
サイズ
符号付き
(Signed)
符号なし
(Unsigned)
Long ULong 64ビット (8バイト)
Integer UInteger 32ビット (4バイト)
Short UShort 16ビット (2バイト)
SByte Byte 8ビット (1バイト)


§2 最小値・最大値

各整数型の最小値・最大値はMinValueMaxValueフィールドを参照することで取得できます。 具体的な値は次のようになります。 なお、表中の16進数表記の値には型のサフィックスを付けています。

整数型の最小値・最大値
最小値 最大値
8ビット整数型 SByte -128
&H80
+127
&H7F
Byte 0
&H00
+255
&HFF
16ビット整数型 Short -32,768
&H8000S
+32,767
&H7FFFS
UShort 0
&H0000US
+65,535
&HFFFFUS
32ビット整数型 Integer -2,147,483,648
&H80000000I
+2,147,483,647
&H7FFFFFFFI
UInteger 0
&H00000000UI
+4,294,967,295
&HFFFFFFFFUI
64ビット整数型 Long -9,223,372,036,854,775,808
&H8000000000000000L
+9,223,372,036,854,775,807
&H7FFFFFFFFFFFFFFFL
ULong 0
&H0000000000000000UL
+18,446,744,073,709,551,615
&HFFFFFFFFFFFFFFFFUL
Imports System

Module Sample
  Public Sub Main()
    Console.WriteLine("signed types")
    Console.WriteLine("{0:N0} 〜 {1:N0}", SByte.MinValue, SByte.MaxValue)
    Console.WriteLine("{0:N0} 〜 {1:N0}", Short.MinValue, Short.MaxValue)
    Console.WriteLine("{0:N0} 〜 {1:N0}", Integer.MinValue, Integer.MaxValue)
    Console.WriteLine("{0:N0} 〜 {1:N0}", Long.MinValue, Long.MaxValue)

    Console.WriteLine("unsigned types")
    Console.WriteLine("{0:N0} 〜 {1:N0}", Byte.MinValue, Byte.MaxValue)
    Console.WriteLine("{0:N0} 〜 {1:N0}", UShort.MinValue, UShort.MaxValue)
    Console.WriteLine("{0:N0} 〜 {1:N0}", UInteger.MinValue, UInteger.MaxValue)
    Console.WriteLine("{0:N0} 〜 {1:N0}", ULong.MinValue, ULong.MaxValue)
  End Sub
End Module
実行結果
signed types
-128 〜 127
-32,768 〜 32,767
-2,147,483,648 〜 2,147,483,647
-9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807
unsigned types
0 〜 255
0 〜 65,535
0 〜 4,294,967,295
0 〜 18,446,744,073,709,551,615

その他各整数型の詳しい特性については型の種類・サイズ・精度・値域を参照してください。

§3 符号なし整数値の代入

符号なし型に値を代入しようとする場合、値の型に注意する必要があります。 例えば、次のようなコードではコンパイルエラーBC30439が発生します。

' UInteger型に値&HFFFFFFFFを代入したい
Dim ui As UInteger = &HFFFFFFFF
' error BC30439: 定数式は、型 'UInteger' では表現できません。

これは、値&HFFFFFFFFがInteger型(符号付き)の数値を表していることが原因で発生するエラーです。 この例では、UInteger型の変数に符号付きの値&HFFFFFFFFつまり-1を代入しようとしていることからエラーとなっています。

このような場合には、値がUInteger型であることを表すサフィックスUIを付けます。 これにより&HFFFFFFFFUIは符号なしの値4294967295を表すことになり、コンパイルエラーは発生しなくなります。

' UInteger型に値&HFFFFFFFFを代入する
Dim ui As UInteger = &HFFFFFFFFUI

サフィックスは型によって異なります。 詳しくはリテラルとサフィックス §.サフィックスをご覧ください。

§4 型の変換

符号付き整数型への変換を行うCIntなどと同様に、符号なし整数型への変換を行う関数が用意されています。

整数型型変換の関数
符号付き型への変換 符号なし型への変換
8ビット整数型への変換 CSByte CByte
16ビット整数型への変換 CShort CUShort
32ビット整数型への変換 CInt CUInt
64ビット整数型への変換 CLng CULng

§4.1 負数から符号なし型への変換

CULongCUIntCUShortなど符号なし型への変換を行う関数ではオーバーフローのチェックが行われます。 そのため、C言語での符号付き型→符号なし型のキャストのようにバイト表現はそのままで型だけを変える、といった目的でCUIntなどを使うことはできません。 値が負の場合にはCUIntは例外OverflowExceptionをスローします。

Dim i As Integer = -1
Dim ui As UInteger = CUInt(i)
' System.OverflowException: 算術演算の結果オーバーフローが発生しました。

こういった場合には、次のように一旦Long型に変換してからバイト表現を符号なしに変更するなど、CUIntに渡す値が負数とならないようにする必要があります。

Dim i As Integer = -1
Dim l As Long = (i And &H7FFFFFFFL) + Integer.MaxValue + 1
Dim ui As UInteger = CUInt(l)

Console.WriteLine(i.ToString("X8"))
Console.WriteLine(ui.ToString("X8"))
実行結果
FFFFFFFF
FFFFFFFF

値が正の場合も考慮した、オーバーフローのチェックを行わないCUIntを関数化すると次のようになります。

Imports System

Module Sample
  ' オーバーフローのチェックを行わずにUIntegerに変換するCUInt
  Public Function CUIntUnchecked(ByVal i As Integer) As UInteger
    If 0 <= i Then
      ' 正または0の場合はそのままUIntegerに変換する
      Return CUInt(i)
    Else
      ' 負の場合はLongに変換して符号なしの値にする
      Dim l As Long = (i And &H7FFFFFFFL) + Integer.MaxValue + 1

      Return CUInt(l)
    End IF
  End Function

  Public Sub Main()
    Console.WriteLine("{0:X8} {1:X8}", 1, CUIntUnchecked(1))
    Console.WriteLine("{0:X8} {1:X8}", 0, CUIntUnchecked(0))
    Console.WriteLine("{0:X8} {1:X8}", -1, CUIntUnchecked(-1))
    Console.WriteLine("{0:X8} {1:X8}", Integer.MaxValue, CUIntUnchecked(Integer.MaxValue))
    Console.WriteLine("{0:X8} {1:X8}", Integer.MinValue, CUIntUnchecked(Integer.MinValue))
  End Sub
End Module
実行結果
00000001 00000001
00000000 00000000
FFFFFFFF FFFFFFFF
7FFFFFFF 7FFFFFFF
80000000 80000000

§5 CLS準拠

符号なし型のULongUIntegerUShortと、符号付き型のSByteは、CLS非準拠な型です。 これらの型をアセンブリ外部に公開するメソッドなどで使用していると、警告BC40028が発生します。

Public Class C
  ' warning BC40028: パラメータ 'val' の型は CLS に準拠していません。
  Public Sub M(ByVal val As SByte)
  End Sub

  ' warning BC40028: パラメータ 'val' の型は CLS に準拠していません。
  Public Sub M(ByVal val As UShort)
  End Sub

  ' warning BC40028: パラメータ 'val' の型は CLS に準拠していません。
  Public Sub M(ByVal val As UInteger)
  End Sub

  ' warning BC40028: パラメータ 'val' の型は CLS に準拠していません。
  Public Sub M(ByVal val As ULong)
  End Sub
End Class

この警告を抑止するには、AssemblyInfo.vbなどに記述されているCLSCompliant属性の引数をFalseにしてプロジェクト(アセンブリ)がCLSに準拠していないことを明示します。

AssemblyInfo.vb
<Assembly: CLSCompliant(False)>

もしくは、原因となるクラスやメソッドなどに対して個別にCLSCompliant属性を指定して、クラスやメソッドがCLSに準拠していないことを明示します。

クラス全体にCLSCompliant属性を適用する例
<CLSCompliant(False)> _
Public Class C
  Public Sub M(ByVal val As SByte)
  End Sub

  Public Sub M(ByVal val As UShort)
  End Sub

  Public Sub M(ByVal val As UInteger)
  End Sub

  Public Sub M(ByVal val As ULong)
  End Sub
End Class
メソッド毎にCLSCompliant属性を適用する例
Public Class C
  <CLSCompliant(False)> _
  Public Sub M(ByVal val As SByte)
  End Sub

  <CLSCompliant(False)> _
  Public Sub M(ByVal val As UShort)
  End Sub

  <CLSCompliant(False)> _
  Public Sub M(ByVal val As UInteger)
  End Sub

  <CLSCompliant(False)> _
  Public Sub M(ByVal val As ULong)
  End Sub
End Class

CLS準拠に関しては言語間の相互運用性と共通言語仕様 (CLS)で詳しく解説しています。