为啥 Java 能够将 0xff000000 存储为 int?
Posted
技术标签:
【中文标题】为啥 Java 能够将 0xff000000 存储为 int?【英文标题】:Why is Java able to store 0xff000000 as an int?为什么 Java 能够将 0xff000000 存储为 int? 【发布时间】:2010-09-24 01:38:43 【问题描述】:Java 中整数的最大值是 2147483647,因为 Java 整数是有符号的,对吧?
0xff000000 的数值为 4278190080。
但我看到这样的 Java 代码:
int ALPHA_MASK = 0xff000000;
谁能赐教?
【问题讨论】:
【参考方案1】:只是对埃里克森回答的补充:
正如他所说,有符号整数在大多数计算机体系结构上存储为它们各自正值的补码。
也就是说,整个 2^32 个可能的值被分成两组:一组用于以 0 位开头的正值,一组用于以 1 开头的负值。
现在,假设我们仅限于 3 位数字。让我们以一种有趣的方式来排列它们,这将在一秒钟内变得有意义:
000
111 001
110 010
101 011
100
您会看到左侧的所有数字都以 1 位开头,而右侧的所有数字都以 0 开头。根据我们之前将前者声明为负数而将后者声明为正数的决定,我们看到 001、010 和 011 是唯一可能的正数,而 111、110 和 101 是它们各自的负数。
现在我们如何处理分别位于顶部和底部的两个数字? 000 显然应该为零,而 100 将是所有没有正数的负数中最小的负数。总结一下:
000 (0)
111 001 (-1 / 1)
110 010 (-2 / 2)
101 011 (-3 / 3)
100 (-4)
您可能会注意到,您可以通过取反 1 (001) 并向其添加 1 (001) 来获得 -1 (111) 的位模式: 001 (= 1) -> 110 + 001 -> 111 (= -1)
回到你的问题:
0xff000000 = 1111 1111 0000 0000 0000 0000 0000 0000
我们不必在它前面添加更多的零,因为我们已经达到了 32 位的最大值。 此外,它显然是一个负数(因为它以 1 位开头),所以我们现在要计算它的绝对值/正对应物:
这意味着,我们将取二的补码
1111 1111 0000 0000 0000 0000 0000 0000
这是
0000 0000 1111 1111 1111 1111 1111 1111
然后我们添加
0000 0000 0000 0000 0000 0000 0000 0001
并获得
0000 0001 0000 0000 0000 0000 0000 0000 = 16777216
因此,0xff000000 = -16777216。
【讨论】:
@Kitsune(和/或任何不知道这一点的人):这是一个很好的解释。可能需要多读几遍,但我建议您通读一遍,直到它真正有意义为止。【参考方案2】:高位是符号位。设置它表示一个负数:-16777216。
与大多数语言一样,Java 以2's complement 形式存储带符号的数字。在这种情况下,从 0x7F000000 或 2130706432 中减去 231 或 2147483648,得到 -16777216。
【讨论】:
【参考方案3】:可能值得指出的一点 - 这段代码不打算用作带有数值的整数;目的是作为位掩码从 32 位颜色值中过滤掉 Alpha 通道。这个变量真的不应该被认为是一个数字,只是一个高 8 位打开的二进制掩码。
【讨论】:
【参考方案4】:额外的位用于符号
Java 整数是 twos complement
【讨论】:
【参考方案5】:int 是用 Java 签名的。
【讨论】:
以上是关于为啥 Java 能够将 0xff000000 存储为 int?的主要内容,如果未能解决你的问题,请参考以下文章
java如何将十六进制0xFF5100A5转换为无符号int值,貌似java不支持无符号数据?