繁体   English   中英

在java中将负int赋给long

[英]Assign negative int to long in java

我有2个整数值存储在bytebuffer中,采用little-endian格式。 这些整数实际上是32位的长整数。 我将它们存储为类的成员变量, loBitshiBits

这就是我做的:

long loBits = buffer.getInt(offset);
long hiBits = buffer.getInt(offset + Integer.BYTES);

我想知道为什么直接将signed int分配给long是错误的。 我知道发生了什么,但真的很感激解释。

我从缓冲区读取的int是签名的(因为Java)。 如果它是负数,那么直接将其分配给long值(或者将其转换为(long) )会将(long)所有高阶位更改为有符号位值。

例如,对于int的十六进制表示, -16841684809b9da0e0 如果我将此int分配给long,则所有更高阶32位将变为F

int negativeIntValue = -1684168480;
long val1 = negativeIntValue;
long val2 = (long) negativeIntValue;

十六进制表示:

negativeIntValue is 0x9b9da0e0
val1 is 0xffffffff9b9da0e0
val2 is 0xffffffff9b9da0e0

但是,如果我使用0x00000000FFFFFFFFL屏蔽negativeIntValue ,我得到一个long,它具有与negativeIntValue相同的十六进制表示和一个正长值2610798816

所以我的问题是:

  • 我的理解是否正确?
  • 为什么会这样?

是的,您的理解是正确的(至少如果我理解您的理解正确)。

发生这种情况的原因是(大多数)计算机使用2的补码来存储有符号值。 因此,当将较小的数据类型分配给较大的数据类型时,该值是符号扩展的,这意味着数据类型的多余部分将填充0或1位,具体取决于原始值是正还是负。

Java中的>>>>>运算符之间的区别也是相关的。 第一个执行符号扩展(保持负值为负)第二个不执行(移动负值使其为正)。

原因是负值存储为二进制补码

为什么我们使用两个补码?

固定宽度编号系统中,如果从0减去1 ,会发生什么?

0000b - 0001b -> 1111b

什么是下一个较小的数字为0 它是-1

因此,我们将所有位设置的二进制数(对于有符号数据类型)设置为-1

最大的优点是当从正数转为负数时,CPU不需要执行任何特殊操作。 它处理5 - 33 - 5相同

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM