如何在Java中执行unsigned to signed转换? [英] How to perform unsigned to signed conversion in Java?

查看:116
本文介绍了如何在Java中执行unsigned to signed转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Say I read these bytes: "6F D4 06 40" from an input device. The number is a longitude reading in MilliArcSeconds format. The top bit (0x80000000) is basically always zero and is ignored for this question.

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

I can easily convert the bytes to an unsigned integer: 1876166208

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

But how do I convert that unsigned value into its final form of 31-bit signed-integer?

到目前为止,我所能想到的只有:

So far all I've come up with is:


  1. if value &安培; 0x40000000然后它实际上是负数,需要转换它

  2. 如果它是负数,则剥离顶部位并对其余位执行某些操作...

所以我可以判断它是否为负数,但为了知道负数是多少,我必须对其余的位做一些事情 - 一个人的恭维?我如何用Java做到这一点?

So I can tell if it's a negative number, but in order to know what value the negative number is, I have to do something with the remaining bits - a one's compliment? How do I do that in Java?

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

Another way to put the question is, how do I convert an unsigned integer into a 31-bit signed integer in Java?

谢谢!

推荐答案

答案取决于低31位你输入的意思是代表。

The answer depends on what the lower 31 bits of your input are meant to represent.

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

无符号输入: 0x6FD40640 == 1876166208

A 二位补码 integer是-1,其中-1设置了所有位,而较低的负数数字从那里开始倒数。第一位仍然作为符号位。

A two's complement integer is one where -1 has all bits set, and lower negatives number count down from there. The first bit still acts as a sign bit.

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

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

If the lower 31 bits represent a two's complement integer, then I think you should just be able to do this:

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

这是因为Java在内部以二进制补码存储整数:我们所做的只是向左移动然后向右移(签名),以便选择符号位,整数从31位变为32位。

That's because Java stores integers in two's complement internally: all we do is shift left and then shift back right (signed) so that the sign bit is picked up and the integer goes from 31 bits to 32 bits.

1的补码数表示是第一位是专用符号位的表示,其余位表示幅度。 -100的低位与100的低位相同:

A one's complement number representation is one where the first bit is a dedicated sign bit, and the remaining bits represent the magnitude. The lower bits of -100 will be the same as the lower bits of 100:

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

如果低31位表示 1的补码整数(即,符号位后跟30位表示无符号幅度),然后需要将其转换为二进制补码,以便Java正确提取值。要做到这一点,你只需要提取低30位并乘以-1:

If the lower 31 bits represent a one's complement integer (that is, a sign bit followed by 30 bits representing an unsigned magnitude), then you need to convert it into two's complement so that Java extracts the value properly. To do this you just need to extract the lower 30 bits and multiply by -1:

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

你在问题​​的评论中说过转换为度数(除以3600000)你得到-75.36左右。 当我将-271317440除以3600000时,我得到-75.36595555555556 ,所以我猜你的输入格式是两个补码,所以我的第一个和原来的答案是正确的。

You said in the question's comments that after converting to degrees (dividing by 3600000) you get around -75.36. When I divide -271317440 by 3600000 I get -75.36595555555556, so I'm guessing your input format is two's complement, so my first and original answer was correct.

这篇关于如何在Java中执行unsigned to signed转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆