我试图理解Java是如何在内部存储整数的。我知道所有的java基本整数都是有符号的(除了short?)。这意味着在一个字节中该数字少了一位可用。
我的问题是,是否所有的整数(正和负)都作为2的补码存储,或者只有负数在2的补码中?
我看到说明书上写着x bit two's complement number
。但我经常感到困惑。
例如:
int x = 15; // Stored as binary as is? 00000000 00000000 00000000 00001111?
int y = -22; // Stored as two complemented value? 11111111 11111111 11111111 11101010
编辑
需要说明的是,x = 15
In binary as is: `00000000 00000000 00000000 00001111'
Two's complement: `11111111 11111111 11111111 11110001`
因此,如果您的答案是all
数字被存储为2的补码,那么:
int x = 15; // 11111111 11111111 11111111 11110001
int y = -22 // 11111111 11111111 11111111 11101010
这里同样令人困惑的是,标牌上写着,两者都是负数。可能是我读错了/误解了?
编辑不确定我的问题是否令人困惑。被迫隔离问题:
准确地说,我的问题是:正数是否存储在binary as is
two's complement
**?**中,而负数是否存储为
有些人说所有的都存储在二的补码中,一个答案说只有负数才存储为二的补码。
发布于 2012-11-17 02:36:49
让我们首先总结一下Java基本数据类型:
Byte :Byte数据类型是一个8位有符号二进制补码整数。
Short :Short数据类型是16位有符号的二进制补码整数。
Int : Int数据类型是32位有符号二进制补码整数。
Long : Long数据类型是64位有符号二进制补码整数。
浮点:浮点数据类型是单精度32位IEEE754浮点。
double :double data type是一种双精度64位IEEE754浮点。
布尔值:布尔值数据类型表示一位信息。
Unicode char :Unicode char数据类型是一个单16位字符。
2的补码
wiki中的一个很好的例子是,通过注意256 = 255 + 1,并且(255−x)是x的1的补码,实现了与2的补码的关系
0000 0111=7的二进制补码是1111 1001= -7
它的工作方式是MSB(最高有效位)接收负值,因此在上面的情况下
-7 = 1001= -8 + 0+ 0+ 1
正整数通常存储为简单二进制数(1表示1,10表示2,11表示3,依此类推)。
负整数存储为2的绝对值的补码。当使用这种记法时,两个正数的补码就是负数。
因为这个答案我得到了几分,所以我决定给它添加更多的信息。
更详细的答案:
在其他方法中,有四种主要方法来表示二进制中的正数和负数,即:
签名Magnitude
的
1.带符号幅度
使用最高有效位表示符号,其余位表示绝对值。其中表示正数,1表示负数,例如:
1011 = -3
0011 = +3
这种表示更简单。但是,您不能以添加十进制数的相同方式添加二进制数,这使得在硬件级别上实现变得更加困难。此外,该方法使用两种二进制模式来表示0,即-0 (1000)和+0 (0000)。
2.一个人的互补
在这个表示中,我们反转给定数字的所有位,以找出其互补性。例如:
010 = 2, so -2 = 101 (inverting all bits).
这种表示的问题在于仍然存在两个位模式来表示0,负0 (1111)和正0 (0000)
3.二进制补码
为了找到一个数字的负数,在这个表示中,我们反转所有的位,然后添加一位。添加一个比特解决了具有表示0的两个比特模式的问题。在此表示法中,我们只有一个用于0 (0000)的模式。
例如,我们想要找出使用4位的4(十进制)的二进制负数表示。首先,我们将4转换为二进制:
4 = 0100
然后我们反转所有的比特
0100 -> 1011
最后,我们添加一位
1011 + 1 = 1100.
因此,如果我们使用具有4位的二进制补码表示法,1100相当于十进制中的-4。
找到互补的一种更快的方法是将第一位固定为值1,并反转剩余的位。在上面的示例中,它类似于:
0100 -> 1100
^^
||-(fixing this value)
|--(inverting this one)
二的补码表示法,除了0只有一个表示法外,它还以与十进制相同的方式将两个二进制值相加,即具有不同符号的偶数。尽管如此,还是有必要检查溢出情况。
4.偏置
此表示法用于表示浮点的IEEE754规范中的指数。它的优点是,所有位都为零的二进制值表示最小值。并且所有位都为1的二进制值表示最大值。顾名思义,该值以带有偏置的n位(通常为2^(n-1)或2^(n-1)-1)的二进制形式进行编码(正或负)。
因此,如果我们使用8位,十进制值1用二进制表示,偏置为2^(n-1),值为:
+1 + bias = +1 + 2^(8-1) = 1 + 128 = 129
converting to binary
1000 0001
发布于 2012-11-17 02:39:46
Java整数是32位的,并且总是有符号的。这意味着,最高有效位(MSB)用作符号位。由int
表示的整数只不过是位的加权和。按如下方式指定权重:
Bit# Weight
31 -2^31
30 2^30
29 2^29
... ...
2 2^2
1 2^1
0 2^0
请注意,MSB的权重为负数(实际上可能是最大的负数),因此此位为on时,整数(加权和)为负数。
让我们用4位数字来模拟它:
Binary Weighted sum Integer value
0000 0 + 0 + 0 + 0 0
0001 0 + 0 + 0 + 2^0 1
0010 0 + 0 + 2^1 + 0 2
0011 0 + 0 + 2^1 + 2^0 3
0100 0 + 2^2 + 0 + 0 4
0101 0 + 2^2 + 0 + 2^0 5
0110 0 + 2^2 + 2^1 + 0 6
0111 0 + 2^2 + 2^1 + 2^0 7 -> the most positive value
1000 -2^3 + 0 + 0 + 0 -8 -> the most negative value
1001 -2^3 + 0 + 0 + 2^0 -7
1010 -2^3 + 0 + 2^1 + 0 -6
1011 -2^3 + 0 + 2^1 + 2^0 -5
1100 -2^3 + 2^2 + 0 + 0 -4
1101 -2^3 + 2^2 + 0 + 2^0 -3
1110 -2^3 + 2^2 + 2^1 + 0 -2
1111 -2^3 + 2^2 + 2^1 + 2^0 -1
因此,二进制补码并不是表示负整数的排他性方案,相反,我们可以说整数的二进制表示总是相同的,我们只是否定了最高有效位的权重。该位决定了整数的符号。
在C中,有一个关键字unsigned
(在java中不可用),可以用来声明unsigned int x;
。在无符号整数中,MSB的权重是正的(2^31
),而不是负的。在这种情况下,unsigned int
的范围是0
到2^32 - 1
,而int
的范围是-2^31
到2^31 - 1
。
从另一个角度来看,如果您认为x
的两个补码是~x + 1
(而不是x加1),那么可以这样解释:
对于任何x
,~x
只是x
的逐位逆,所以无论x
在哪里有1
-bit,~x
都会在那里有一个0
-bit (反之亦然)。所以,如果你把这些加起来,在加法中不会有进位,和只是一个整数,它的每一位都是1
。
对于32位整数:
x + ~x = 1111 1111 1111 1111 1111 1111 1111 1111
x + ~x + 1 = 1111 1111 1111 1111 1111 1111 1111 1111 + 1
= 1 0000 0000 0000 0000 0000 0000 0000 0000
最左边的1
-bit将被简单地丢弃,因为它不适合32位(整数溢出)。所以,
x + ~x + 1 = 0
-x = ~x + 1
所以你可以看到负的x
可以用~x + 1
来表示,我们称之为x
的2的补码。
发布于 2012-11-17 02:36:37
我已经运行了下面的程序来了解它
public class Negative {
public static void main(String[] args) {
int i =10;
int j = -10;
System.out.println(Integer.toBinaryString(i));
System.out.println(Integer.toBinaryString(j));
}
}
输出为
1010
11111111111111111111111111110110
从输出来看,它似乎一直在使用2的补码。
https://stackoverflow.com/questions/13422259
复制相似问题