java - 如何在 Java 中执行无符号到有符号的转换?

标签 java type-conversion signed

假设我从输入设备读取了这些字节:“6F D4 06 40”。该数字是 MilliArcSeconds 格式的经度读数。最高位 (0x80000000) 基本上始终为零,对于此问题将被忽略。

我可以轻松地将字节转换为无符号整数:1876166208

但是我如何将该无符号值转换为 31 位有符号整数的最终形式?

到目前为止我想出的是:

  1. 如果value & 0x40000000那么它实际上是负数,需要转换它
  2. 如果它是负数,去掉最高位并对剩下的位做一些事情...

所以我可以判断它是否为负数,但为了知道负数的值是多少,我必须对剩余的位做一些事情 - 一个人的恭维?我如何在 Java 中执行此操作?

问题的另一种表达方式是,如何在 Java 中将无符号整数转换为 31 位有符号整数?

谢谢!

最佳答案

答案取决于输入的低 31 位要表示什么。

int input = 0x6FD40640 & 0x7FFFFFFF; //strip top bit; only here for clarity

无符号输入:0x6FD40640 == 1876166208

二进制补码(所需输出:-271317440)

二进制补码 整数是 -1 设置了所有位,较低的负数从那里倒数。第一位仍然作为符号位。

1000 -> -8
1001 -> -7
...
1110 -> -2
1111 -> -1
0000 ->  0
0001 ->  1

如果低 31 位表示二进制补码整数,那么我认为您应该能够这样做:

input = (input << 1) >> 1;

那是因为 Java 在内部以二进制补码存储整数:我们所做的只是左移然后右移(有符号),以便拾取符号位并且整数从 31 位变为 32 位。

一个的补码(期望输出:-802424384)

one's complement 数字表示是其中第一位是专用符号位,其余位表示大小。 -100 的低位将与 100 的低位相同:

 1111 -> -7
 1110 -> -6
 ...
 1001 -> -1
 1000 -> -0 (anomoly)
 0000 ->  0
 0001 ->  1

如果低31位表示一个补码整数(即一个符号位后面跟着30位表示一个无符号的大小),那么就需要将其转换成补码,以便Java提取正确的值(value)。为此,您只需提取低 30 位并乘以 -1:

if ( input & 0x40000000 ) {
   input = (input & 0x3FFFFFFF) * -1;
}

您在问题的评论中说,在转换为度数(除以 3600000)后,您得到大约 -75.36。 当我将 -271317440 除以 3600000 时,我得到 -75.36595555555556,所以我猜你的输入格式是二进制补码,所以我的第一个和最初的答案是正确的。

关于java - 如何在 Java 中执行无符号到有符号的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3935304/

相关文章:

java - Łukasiewicz 谓词逻辑?

java - ScreenCap 直接 toByteArray ,跳过保存到内存

java - JDBC 连接被拒绝,默认用户名密码?

C:类型冲突错误

C++:了解我的计算机如何存储字节

Java:4 字节到 32 位整数

c++ - 当我计算一个大的阶乘时,为什么我得到一个负数?

java - 从字节数组组重新创建文件

c - 十六进制到十进制的转换

java - 如何将字符串 23323.00 转换为长整型