2013-08-09T22:25:09の更新内容

programming/vb.net/unsigned_types/index.wiki.txt

current previous
1,230 1,101
~
${smdncms:title,符号なし整数型}
${smdncms:title,Unsigned型}
~
${smdncms:header_title,符号なし整数型(Unsigned型)}
${smdncms:keywords,Unsigned,ULong,UInt,UShort,SByte}
+
${smdncms:keywords,Unsigned,符号なし,アンサインド,ULong,UInt,UShort,Byte,CLS}
 
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,visual basic}
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,visual basic}
~

          
#navi(..)
~
VB8(VB2005)以降では符号なし整数型を使うことができます。 ULongは64ビット、UIntegerは32ビット、UShortは16ビットの符号なし整数です。 VB7以前から存在した8ビットの符号なし整数Byteも引き続き使えます。
VB8ではUnsigned型が導入されました。 64bit長のULong、32bit長のUInt、16bit長のUShortです。 さらに符号付き8bit長の整数型として、SByteも導入されました。 これで整数型に関して言えばC#と同じ種類が揃ったわけです。 これらは、CLR型でいうとそれぞれSystem.UInt64、System.UInt32、System.UInt16、System.SByteと同じものです。
+

          
 
#googleadunit
#googleadunit
 

        

        
+
*ULong・UInteger・UShort
+
符号付き整数型のLong・Integer・Shortに対応する符号なし(''U''nsigned)整数型はそれぞれULong・UInteger・UShortとなります。 8ビットの符号なし整数型Byteに対応する符号付き(''S''igned)整数型はSByteとなります。 対応関係は次のとおりです。
+

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

          
+
*最小値・最大値
+
各整数型の最小値・最大値はMinValue・MaxValueフィールドで取得できます。 具体的な値は次のようになります。 なお、表中の16進数表記の値には[[型のサフィックス>programming/netfx/basic_types/1_literal_suffix#Suffixes]]を付けています。
+

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

          
 
#code(vb){{
#code(vb){{
 
Imports System
Imports System
 

        

        
~
Module Sample
Class UnsignedTypes
+
  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
+
}}
 

        

        
~
#prompt(実行結果){{
    Public Shared Sub Main()
+
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
+
}}
 

        

        
~
その他各整数型の詳しい特性については[[programming/netfx/basic_types/0_characteristics]]を参照してください。
        Console.WriteLine("signed")
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(Long), Long.MinValue, Long.MaxValue)
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(Integer), Integer.MinValue, Integer.MaxValue)
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(Short), Short.MinValue, Short.MaxValue)
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(SByte), SByte.MinValue, SByte.MaxValue)
-

          
-
        Console.WriteLine("unsigned")
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(ULong), ULong.MinValue, ULong.MaxValue)
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(UInteger), UInteger.MinValue, UInteger.MaxValue)
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(UShort), UShort.MinValue, UShort.MaxValue)
-
        Console.WriteLine("type:{0} min:{1}, max:{2}", GetType(Byte), Byte.MinValue, Byte.MaxValue)
 

        

        
-
    End Sub
 

        

        
~
*符号なし整数値の代入
End Class
+
符号なし型に値を代入しようとする場合、値の型に注意する必要があります。 例えば、次のようなコードではコンパイルエラー&msdn(netfx,id,3k2faaft){BC30439};が発生します。
+

          
+
#code(vb){{
+
' UInteger型に値&HFFFFFFFFを代入したい
+
Dim ui As UInteger = &HFFFFFFFF
 
}}
}}
 

        

        
~
#prompt{{
#prompt(実行結果){{
~
error BC30439: 定数式は、型 'UInteger' では表現できません。
signed
-
type:System.Int64 min:-9223372036854775808, max:9223372036854775807
-
type:System.Int32 min:-2147483648, max:2147483647
-
type:System.Int16 min:-32768, max:32767
-
type:System.SByte min:-128, max:127
-
unsigned
-
type:System.UInt64 min:0, max:18446744073709551615
-
type:System.UInt32 min:0, max:4294967295
-
type:System.UInt16 min:0, max:65535
-
type:System.Byte min:0, max:255
 
}}
}}
 

        

        
~
これは、値``&HFFFFFFFF``がInteger型の数値を表しているためで、UInteger型の変数に``&HFFFFFFFF``つまり``-1``を代入しようとしていることからエラーとなっています。
またこれに伴って、型変換用のCULong、CUInt、CUShort、CSByteも追加されました。
+

          
+
このような場合には、値がUInteger型であることを表すサフィックス``UI``を付けます。
 

        

        
 
#code(vb){{
#code(vb){{
~
' UInteger型に値&HFFFFFFFFを代入する
Imports System
+
Dim ui As UInteger = &HFFFFFFFFUI
+
}}
 

        

        
~
こうすることによりコンパイルエラーが発生しなくなります。
Class UnsignedTypes
 

        

        
~
サフィックスは型によって異なります。 詳しくは[[programming/netfx/basic_types/1_literal_suffix#Suffixes]]をご覧ください。
    Public Shared Sub Main()
 

        

        
-
        Console.WriteLine("{0}", CLng(3).GetType)
-
        Console.WriteLine("{0}", CULng(3).GetType)
-
        Console.WriteLine("{0}", CInt(3).GetType)
-
        Console.WriteLine("{0}", CUInt(3).GetType)
-
        Console.WriteLine("{0}", CShort(3).GetType)
-
        Console.WriteLine("{0}", CUShort(3).GetType)
-
        Console.WriteLine("{0}", CByte(3).GetType)
-
        Console.WriteLine("{0}", CSByte(3).GetType)
 

        

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

        

        
~
#code(vb){{
    End Sub
+
Dim i As Integer = -1
+
Dim ui As UInteger = CUInt(i)
+
' System.OverflowException: 算術演算の結果オーバーフローが発生しました。
+
}}
 

        

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

          
+
#code(vb){{
+
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"))
 
}}
}}
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
FFFFFFFF
System.Int64
~
FFFFFFFF
System.UInt64
-
System.Int32
-
System.UInt32
-
System.Int16
-
System.UInt16
-
System.Byte
-
System.SByte
 
}}
}}
 

        

        
~
値が正の場合についても考慮してオーバーフローのチェックを行わないCUIntを関数化すると次のようになります。
また、符号無し型の数値にサフィックスを付ける場合は符号付き型のサフィックスの前にUを付けたものを使います。
 

        

        
 
#code(vb){{
#code(vb){{
~
Imports System
Dim signedLong As Long = 3L
-
Dim signedInteger As Integer = 3I
-
Dim signedShort As Short = 3S
-
Dim signedByte As SByte = 3
 

        

        
~
Module Sample
Dim unsignedLong As ULong = 3UL
~
  ' オーバーフローのチェックを行わずにUIntegerに変換するCUInt
Dim unsignedInteger As UInteger = 3UI
~
  Public Function CUIntUnchecked(ByVal i As Integer) As UInteger
Dim unsignedShort As UShort = 3US
~
    If 0 <= i Then
Dim unsignedByte As Byte = 3
+
      ' 正または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} {0:X8}", 1, CUIntUnchecked(1))
+
    Console.WriteLine("{0:X8} {0:X8}", 0, CUIntUnchecked(0))
+
    Console.WriteLine("{0:X8} {0:X8}", -1, CUIntUnchecked(-1))
+
    Console.WriteLine("{0:X8} {0:X8}", Integer.MaxValue, CUIntUnchecked(Integer.MaxValue))
+
    Console.WriteLine("{0:X8} {0:X8}", Integer.MinValue, CUIntUnchecked(Integer.MinValue))
+
  End Sub
+
End Module
+
}}
 

        

        
~
#prompt(実行結果){{
Dim singleFloat As Single = 3.0F
~
00000001 00000001
Dim doubleFloat As Double = 3.0R ' 3.0でもDouble型となる
~
00000000 00000000
Dim fixedFloat As Decimal = 3D
+
FFFFFFFF FFFFFFFF
+
7FFFFFFF 7FFFFFFF
+
80000000 80000000
 
}}
}}
 

        

        
-
なお、ByteとSByteに対応するサフィックスはありません。
 

        

        
~
*CLS準拠
#navi(..)
+
符号なし型のULong・UInteger・UShortと、符号付き型のSByteは、''CLS非準拠''な型です。 これらの型をアセンブリ外部に公開するメソッドなどで使用していると、警告&msdn(netfx,id,80s5t69h){BC40028};が発生します。
+

          
+
#code(vb){{
+
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に準拠していないことを明示します。
+

          
+
#code(vb,AssemblyInfo.vb){{
+
<Assembly: CLSCompliant(False)>
+
}}
+

          
+
もしくは、原因となるクラスやメソッドなどに対して個別にCLSCompliant属性を指定します。
+

          
+
#code(vb,クラス全体に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
+
}}
+

          
+
#code(vb,メソッド毎に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準拠に関しては[[programming/netfx/classlibrary/1_interoperability]]で詳しく解説しています。
+

          
+