なぜデータ型の範囲が正側と比較して負側で大きいのですか?
たとえば、整数の場合:
Turbo Cの範囲は-32768
から32767
およびVisual Studioの場合-2147483648
から2147483647
。
同じことが他のデータ型にも起こります...
[UPD:Visual Studio]に適切な制限値を設定します
数字の保存方法のため。符号付き数値は、「2の補数表記」と呼ばれるものを使用して保存されます。
すべての変数には一定量のビットがあることに注意してください。それらの最も重要なもの、左側のものが0の場合、数値は非負(つまり、正またはゼロ)であり、残りのビットは単に値を表します。
ただし、左端のビットが1の場合、数値は負になります。数値の実際の値は、表示される整数(左端の1を含む符号なしの量として)から2 ^ nを引くことで取得できます。ここで、nは変数のビット数です。
数値の実際の値(「仮数」)にはn-1ビットのみが残っているため、可能な組み合わせは2 ^(n-1)です。正/ゼロの数値の場合、これは簡単です。0から2 ^(n-1)-1になります。その-1はゼロ自体を考慮に入れることです。たとえば、可能な組み合わせが4つしかない場合、それらの組み合わせ0、1、2、および3を表します(4つの数字があることに注意してください):0から4-1になります。
負の数については、左端のビットが1であることを思い出してください。したがって、表示される整数は2 ^(n-1)〜(2 ^ n)-1の間になります(括弧は非常に重要です!)。しかし、私が言ったように、数値の実際の値を得るには2 ^ nを奪わなければなりません。 2 ^(n-1)-2 ^ nは-(2 ^(n-1))であり、((2 ^ n)-1)-2 ^ nは-1です。したがって、負の数の範囲は-(2 ^(n-1))〜-1です。
すべてをまとめると、-2 ^(n-1)〜2 ^(n-1)-1になります。ご覧のとおり、上限は-1になりますが、下限はそうではありません。
そして、それが正の数よりも負の数のほうが多い理由です。
Cが必要とする最小範囲は、実際には-32767〜32767です。これは、2の補数、1の補数、および負の数の符号/大きさのエンコーディングに対応する必要があるためです。データ型の最小範囲の詳細については、C11(およびC99)のAnnex E, Implementation limits
を参照してください。
あなたの質問は2の補数バリアントのみに関係し、その理由は簡単です。 16ビットでは、2を表すことができます16 (または65,536)異なる値とゼロはそれらの1つでなければなりません。したがって、奇数の値が残っており、その大部分(1つ)は負の値です。
1 thru 32767 = 37267 values
0 = 1 value
-1 thru -32768 = 32768 values
-----
65536 values
1の補数と符号マグニチュードエンコーディングの両方で、負のゼロ値(および正のゼロ)が許可されます。これは、非ゼロの数値で使用可能なビットパターンが1つ少ないため、標準で見られる最小範囲の縮小。
1 thru 32767 = 37267 values
0 = 1 value
-0 = 1 value
-1 thru -32767 = 32767 values
-----
65536 values
正と負の数を同じ単純なハードウェアで追加できるため、2の補数は実際には気の利いたエンコードスキームです。他のエンコード方式では、同じタスクを実行するためにより複雑なハードウェアが必要になる傾向があります。
2の補数がどのように機能するかについての詳細な説明については、 wikipediaページ を参照してください。
範囲にゼロが含まれているため。 nビット整数が表すことができる異なる値の数は2 ^ nです。つまり、16ビット整数は65536個の異なる値を表すことができます。符号なし16ビット整数の場合、0〜65535(両端を含む)を表すことができます。符号付き整数の規則は、-32768〜32767、-214748368〜214748367などを表すことです。
2の補数では、負の数はビット単位ではなく1として定義されます。これにより、負の側で指定されたビット数で可能な数の範囲が1減ります。
通常、負の値を格納するために2の補数システムを使用しているため、整数の符号ビットを反転すると、負の方向にバイアスがかかります。
範囲は次のとおりです。-(2 ^(n-1))-((2 ^(n-1)-1)