【问题标题】:Re: Convert Double to byte[] arrayRe: 将 Double 转换为 byte[] 数组
【发布时间】:2013-12-09 04:51:41
【问题描述】:


参考 (Double to byte[]) 它包含了我需要的问题和解决方案。

private byte[] convert(Double d) {
    byte[] output = new byte[8];
    Long lng = Double.doubleToLongBits(d);
    for (int i = 0; i < 8; i++) {
        output[i] = (byte)((lng >> ((7 - i) * 8)) & 0xff);
    }
    return output;
}

但我不知道它是如何/为什么工作的,我知道循环将构成 Double 的 8 个字节中的每一个分配给数组。但我不明白字节是如何构造的。有人可以向我解释以下表达式吗?

 ((lng >> ((7 - i) * 8)) & 0xff);

为什么Double.doubleToLongBits(d); 参与其中?

【问题讨论】:

  • 你问运营商是做什么的?

标签: java type-conversion double byte


【解决方案1】:

让我们分解一下这个表达式:

((lng >> ((7 - i) * 8)) & 0xff);

一步一步来。 ((7 - i) * 8) 应该很明显。 &gt;&gt; 是二元右移运算符。它将左操作数旋转从左填充 MSB 的右操作数位数。因此,lng 在每次迭代中旋转了(7-i) 字节数。

&amp; 是按位与运算符,这意味着如果两个操作数的相同位位置都有 1,则得到 1,否则为 0。因此,基本上与 0xff 进行与运算基本上给了我们最后一个旋转后的lng 的字节。

总而言之,您从每次迭代中的最高有效字节开始获取 lng 的每个字节。

要回答问题的第二部分,请尝试直接旋转双精度值的位(您会得到一个严重的错误)。在 Java 中,double 和 long 使用相同的字节数(8),因此如果要进行按位运算,则必须先将 double 值转换为 long。

【讨论】:

  • 否,>> 填充 MSB 的值。如果你想要 0,请使用 >>>。
  • *8 因为字节中有 8 位。 7-i 因为我们要关注的字节位置。 &gt;&gt; 将 long 旋转 ((7-1)*8) 个位位置。 &amp; 0xff 因为 255 是一个字节的最大值,而最后一个字节之间的“重叠”是我想要的。对吗?
  • 除此之外都是正确的:&amp; 0xff,因为它都是一。 255 是 0x7f - 第一位 0 其余位 1。
【解决方案2】:

Double#doubleToLongBitsIEEE 754 格式创建值的 64 位表示形式。

循环获取所有 64 位,从最高有效位开始,并将它们存储在一个 8 字节数组中。

lng = 0x123456789abcdef0

(byte)((lng >> ((7 - 0) * 8)) & 0xff) == (byte) 0x12
(byte)((lng >> ((7 - 1) * 8)) & 0xff) == (byte) 0x34
(byte)((lng >> ((7 - 2) * 8)) & 0xff) == (byte) 0x56
(byte)((lng >> ((7 - 3) * 8)) & 0xff) == (byte) 0x78
(byte)((lng >> ((7 - 4) * 8)) & 0xff) == (byte) 0x9a
(byte)((lng >> ((7 - 5) * 8)) & 0xff) == (byte) 0xbc
(byte)((lng >> ((7 - 6) * 8)) & 0xff) == (byte) 0xde
(byte)((lng >> ((7 - 7) * 8)) & 0xff) == (byte) 0xf0

【讨论】:

    【解决方案3】:

    想法是将一个整数值右移(这是右移运算符>>),然后用(&amp; 0xff)取最后8位。

    例如,如果您想要长 n 右侧的第三个字节

    (n >> (2*8)) & 0xff
    

    doubleToLongBits 是必需的,因为您不能移动浮点值的位,只能移动整数值。因此,此方法只为您提供 double as long 值的位模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-18
      • 2016-05-25
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      • 2020-05-17
      • 1970-01-01
      • 2014-03-05
      相关资源
      最近更新 更多