假设我从输入设备读取了这些字节:“6F D4 06 40”。该数字是 MilliArcSeconds 格式的经度读数。最高位 (0x80000000) 基本上始终为零,对于此问题将被忽略。
我可以轻松地将字节转换为无符号整数:1876166208
但是我如何将该无符号值转换为 31 位有符号整数的最终形式?
到目前为止我想出的是:
- 如果value & 0x40000000那么它实际上是负数,需要转换它
- 如果它是负数,去掉最高位并对剩下的位做一些事情...
所以我可以判断它是否为负数,但为了知道负数的值是多少,我必须对剩余的位做一些事情 - 一个人的恭维?我如何在 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/