java如何录入符号_如何在Java中执行从无符号到有符号的转换?

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

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

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

到目前为止,我只想出了:

如果value&0x40000000那么它实际上是负数,需要将其转换

如果是负数,则剥离最高位,然后对其余位进行一些处理...

因此,我可以判断它是否为负数,但是为了知道负数是什么值,我必须对其余的位做些什么-一个恭维吗? 如何在Java中做到这一点?

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

谢谢!

我想我在回答中误解了你的问题。您可以根据示例输入说出想要带符号整数的值是什么吗?你从没说过

输入:" 6F D3 FD 45"。输出:大约-75.366465。我说大概是因为我找到了一个地点并留在那里收集数据,同时使用GPS测量了位置。因此,上面的经度(-75.366465)应该接近,但可能不完全相同,与上述十六进制字节转换为有符号整数(并执行MAS至度数转换)的值相同。我试图找到一种方法来使用Java从十六进制字节转换为带符号的int

MAS至学位:除以3,600,000。

越来越近...去除"负位"的实际读数:" 2F D3 FD 45" ...将其与" 10 2C 00 EA"的-75.366465的预期MAS值进行比较...如果我翻转,则前22位匹配1到0和0到1(XOR)。我认为这可能是诀窍-需要翻转所有位...我可以使用XOR做到这一点...

@Mark-您是正确的。我很抱歉。

答案取决于输入的低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)

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

1111 -> -7

1110 -> -6

...

1001 -> -1

1000 -> -0 (anomoly)

0000 ->  0

0001 ->  1

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

if ( input & 0x40000000 ) {

input = (input & 0x3FFFFFFF) * -1;

}

您在问题的评论中说,转换为度(除以3600000)后,您可以获得-75.36左右。当我将-271317440除以3600000时,我得到-75.36595555555556,因此我猜测您的输入格式为二进制补码,因此我的第一个和原始答案是正确的。

看起来会成功。但是不确定& 0x7FFFFFFF是否必要。

似乎&7fffffff和左/右移位做了同样的事情(删除最左边的最高位)?我正在努力获取一些示例数据,因此我们可以对其进行测试

@Alison:不能仅仅用来证明输入只是低31位,而高位是无关紧要的。第二行是我要显示的内容,但是Brad尚未确认这是否是所需的输出。

@Brad:只需按&7FFFFFFF进行"与"运算就可以清除最高位。这会向左移动,但以符号扩展的方式向右移动。换句话说,它用第二位填充第一位。但是我再次需要查看您想要的输出是什么...我不知道31个低位应该代表什么。

为什么这个答案被投票否决?它根本没有解决这个问题。请重新阅读问题!

将无符号整数读取为带符号整数是确定是否设置了最高有效位(负标志)的问题,如果是,则翻转数字的所有位(从而清除最高有效位,然后将数字切换为负数)。执行上述过程时,还必须注意结果为负数的事实。

// Convert the hex bytes to an unsigned integer

long MAS = Integer.ValueOf("6F D4 06 40".replace ("",""),16);

boolean isLongitudeNegative = false;

// Is the negative-bit set? If so, strip it and toggle all bits.

if (MAS & 0x40000000 > 0) {

// then it's negative, so strip the negative bit and flip all the other bits

MAS ^= 0xFFFFFFFF;

// Throw away the unused bit.

MAS &= 0x7FFFFFFF;

isLongitudeNegative = true;

}

// Now convert from MAS to degrees minutes seconds

String DMS = convertMASToDMS(isLongitudeNegative,MAS);

很抱歉爆发。这个答案是否最终满足了您的要求?如果是这样,请随时接受。唯一的建议是您可能会发现MAS = ~MAS是切换MAS位的更清晰的方法。因此,在给出此解决方案的情况下,我假设输入的低31位表示一个31位的补码整数,而您试图提取该值?那是您要解决的问题吗?

再次检查我的答案。我很确定我的原始答案是正确的。当我将转换应用于您的样本输入,然后除以3600000时,我得到-75.369555,这是您的预期输出。当我进行转换时,我会得到-222的提示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值