java - 左移丢失的信息是否存储在 Java 中的某个地方?
问题描述
所以我在 Java 中尝试左移,我发现了一些我不理解的东西。下面的代码描述了它。
int x = -1 << 31;
System.out.print(Integer.toBinaryString(-1) + " -1\n");
System.out.print(Integer.toBinaryString(x) + " " + x + "\n");
// output
11111111111111111111111111111111 -1
10000000000000000000000000000000 -2147483648
所以我只是去掉了整数-1左边的31个1,结果如我所愿。但是,在我尝试再左移 1 个位置后,我得到的不是 0,而是 -1。
int x = -1 << 32; // one more left shift
System.out.print(Integer.toBinaryString(-1) + " -1\n");
System.out.print(Integer.toBinaryString(x) + " " + x + "\n");
// output
11111111111111111111111111111111 -1
11111111111111111111111111111111 -1
然后我尝试将最小整数值 -2147483648 直接左移 1。我得到了预期值 0。
System.out.println(-2147483648 << 1); // the output is 0
有人可以向我解释幕后发生的事情吗?
解决方案
这是JLS 15.19:
如果左侧操作数的提升类型是 int,则只有右侧操作数的五个最低位用作移位距离。就好像右手操作数受到按位逻辑与运算符 & (§15.22.1) 的影响,掩码值为 0x1f (0b11111)。因此,实际使用的移位距离始终在 0 到 31 的范围内,包括 0 到 31。
所以-1 << 32
是一样的-1 << 0
,解释你的结果。
推荐阅读
- amazon-cognito - AWS Cognito 回调 URL 中的查询字符串参数
- google-people-api - Google People API 不会为 people/me 返回 emailAddress
- types - 在 Elm 中使用 NoMap 在初始化时使用 http 请求映射 Msg
- c# - 基于其他 DataGrid 中的 SelectedItem 在 DataGrid 中显示对象变量
- java - Hibernate Search 仅索引我的部分实体
- image - 在 Image 组件中使用 Expo 显示所选照片 - React Native
- node.js - 指定不应在 Swagger 或 OpenAPI 中发送的属性
- javascript - 如何在 Javascript 和 Ajax 中正确回调(无 jQuery)
- amazon-web-services - Kubernetes集群迁移
- php - mysqli 使用 select * 和准备好的语句和查询