【问题标题】:Split 64-bit value to four 16-bit将 64 位值拆分为四个 16 位
【发布时间】:2023-03-05 02:06:01
【问题描述】:

我有这样的 64 位值:

1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0011

给定数字流的十进制值为-45。

我想分成四个 16 位值:

1111 1111 1111 1111
1111 1111 1111 1111
1111 1111 1111 1111
1111 1111 1101 0011

输入值是有符号长的。

如何在 Java 中做到这一点?

到目前为止,我已经尝试过这种方式:

long[] buf = new long[4];
buf[0] =  (l&0xFF);
buf[1] =  (l&0xFF >> 16) & 0XFF;
buf[2] =  (l&0xFF >> 32) & 0XFF;
buf[3] =  (l&0xFF >> 48) & 0XFF;

但我认为我在移位逻辑方面搞砸了。

编辑

感谢@Eugene,正确的解决方案是:

long l = 45;

long[] buf = new long[4];
buf[0] =  (l & 0xFFFF);
buf[1] =  l  >> 16 & 0XFFFF;
buf[2] =  l  >> 32 & 0XFFFF;
buf[3] =  l  >> 48 & 0XFFFF;

long result = ( buf[3] & 0xFFFF) << 48 | ( buf[2] & 0xFFFF) << 32 | (buf[1] & 0xFFFF) << 16 | (buf[0] & 0xFFFF);

System.out.println("Decimal: " + result);
System.out.println("Binary: "Long.toBinaryString(result));

【问题讨论】:

  • 是否存储为字符串?您的 64 位值是否称为“输入值”?
  • 它不存储为字符串。它像长数据类型一样存储。我不太了解的部分是位操作。对于每组 16 位,结果应该是四个元素的数组。
  • 欢迎来到 Stack Overflow!请拿起tour,环顾四周,并通读help center,尤其是How do I ask a good question? 和What topics can I ask about here?。从第二个链接:“要求家庭作业帮助的问题必须包括您迄今为止为解决问题所做的工作的摘要,以及您在解决问题时遇到的困难的描述。” ——就算没有作业……

标签: java 64-bit bit-manipulation 16-bit


【解决方案1】:

编辑

您几乎是正确的(我打字太多,认为您也需要基础知识,我的错)。

您只需更改:buf[1] = l &gt;&gt; 16 &amp; 0xFFFF;

我本可以用不同的方式写它,但这可能是最容易理解的:

 long t = Long.parseUnsignedLong("1111111111111111111111111111111111111111111111111111111111010011", 2);

    long twoPower16 = Long.parseLong("1111111111111111", 2);

    long one = t & twoPower16;
    long two = t >> 16 & twoPower16;
    long thr = t >> 32 & twoPower16;
    long fou = t >> 48 & twoPower16;

    System.out.println(Long.toBinaryString(one));
    System.out.println(Long.toBinaryString(two));
    System.out.println(Long.toBinaryString(thr));
    System.out.println(Long.toBinaryString(fou));

当你进行&amp; 操作(称为掩码)时,例如:

   0101
   0011
   ----
   0001 --> you are keeping the last two bits here 

&gt;&gt; 是移位运算符。你告诉要移动多少位:

 System.out.println(7 >> 1); // 3

这实际上是0111 &gt;&gt; 1 --> 0011,您将7 向左移动了一点。

【讨论】:

  • @Josef 在我的回答中看到编辑 - 你几乎在那里。
  • 所以,正确的解决方案是:buf[0] = ( l & 0xFF); buf[1] = l >> 16 & 0XFF; buf[2] = l >> 32 & 0XFF; buf[3] = l >> 48 & 0XFF;对吗?
  • 但是为什么当我想以这种方式转换回原来的时候 long result = ( buf[3] & 0xFF)
  • @Josef 问题出在0xFF,应该是0xFFFF
  • 对不起,也许我做错了什么,但即使我更改为 0xFFFF,我也无法取回正确的值。 long[] buf = 新的 long[4]; buf[0] = (l & 0xFFFF); buf[1] = l >> 16 & 0XFFFF; buf[2] = l >> 32 & 0XFFFF;buf[3] = l >> 48 & 0XFFFF;长结果 = ( buf[0] & 0xFFFF)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 2013-12-01
  • 2023-03-08
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多