それは、コンピューターの算術が2 の補数に基づいているためです。
あなたはColpementの方法について読むべきです
たとえば、10 進数の補数では、自然な減算は次のようになります (4 桁を使用):
0000
0001 -
9999 =
補数システムでは最初の桁(もちろんビッグエンディアンでは、エンディアンに精通している必要があります)が符号を定義するため、明らかに-1です。たとえば、10 進数の補数では、4 は 4、4 は 4、3 は 3、2 は 2、1 は 1、0 は 0、9 は -1、8 は -2、7 は -3、6 は -4、5 です。は -5 です。
これは、補数システムでは、常に同じ桁数で操作しますが、オーバーフローした結果を無視することを除いて、常に加算と減算を行っているためです。たとえば、10 進数が 2 桁の場合:
04
05 -
...9999 =
私が言ったように、結果は 2 桁しかない (2 桁を追加した) ため、結果は 99 です。前にも述べたように、最初の数値は (9 ではなく) -1 として解釈されます。これは位置番号システムであるため、この結果を通常の 10 進法に簡単に変換できます。正しい 10 の累乗で乗算する数字を合計するだけです。
10^1 * 9 + 10^0 * 9
//as I told - first nine is -1 so:
10^1 * -1 + 10^0*9 = -10 + 9 = -1
最初の結果で試してください:
9999 = 9 * 10^3 + 10^2 * 9 + 10^1 * 9 + 10^0 * 9
//first nine is -1 so:
-1 * 10^3 + 999 = -1000 + 999 = -1
バイナリでは、最初の数値が符号が何であるかを示すだけなので、はるかに簡単です。8ビットの数値で試してください:
1111 1111
1 を足すと結果が 0 になるので、明らかに -1 です。
1111 1111
0000 0001 +
1 0000 0000 =
しかし、補体系では正しくありません。それは、補体系では最初の桁が数の符号を記述するだけでなく、すべての数がその桁によって無限に拡張できるからです! これが、id が 10 進数 99 = 9999 を補う理由です。また、8 バイトの数値をたとえば 32 バイトに簡単に拡張できることも意味します。
たとえば、数字の 17 と -1 を試してみてください。あなたは今、-1 に精通しています。8 バイトの 2 の複素数 -1 は次のとおりです。
1111 1111
32 バイトに拡張すると、次のようになります。
1111 1111 1111 1111 1111 1111 1111 1111
それを通常の 10 進法に変換するには、2^31 + 2^30 + ... + 2^0 を実行する必要がありますが、(前述したように) 最初の 1 は -1 なので、正確には -1 * 2^31 + 2^30 です。 + .. + 2^0 これを計算すると、正確には -2147483648 + 2147483647 = -1 !
0001 0001 (10 進数 17)
32 バイトに拡張すると、次のようになります。
0000 0000 0000 0000 0000 0000 0001 0001
そして、まだ17歳であることは同意できます:)
私が頭がおかしいわけではなく、IT の学生であることを示すために、まさにそのようなことを行う C++ コードを紹介します。
#include <iostream>
using namespace std;
int main(void)
{
char eightBits = 255; //eightBits := 0x11111111
int eightBytes = eightBits; //eightBytes becaming 255, right?
cout <<eightBytes <<endl; // MAGIC !
return 0;
}