如何在Java中读取二进制32位定点数

时间:2013-12-17 21:29:46

标签: java ruby

我需要阅读Adobe签名的32位定点数,整数部分为8位,小数部分为24位。这是Adobe Photoshop File Formats Specification中定义的“路径点”。

这就是我在Ruby中的方式,但我需要用Java来完成。

  read(1).unpack('c*')[0].to_f +
    (read(3).unpack('B*')[0].to_i(2).to_f / (2 ** 24)).to_f

2 个答案:

答案 0 :(得分:2)

根据David Wallace的回答中的一些讨论,可以更快地计算出正确的double

转换它的最快方法可能是这样的:

double intFixedPoint24ToDouble(int bits){
    return ((double) bits) / 1<<24;
}

原因这个更快是因为双精度浮点算术的工作方式。在这种情况下,上述序列可以转换为一些非常简单的加法和位移。当它运行时,它采取的实际步骤如下所示:

  1. intbits)转换为double(通常在FPU上完成)。这很快。
  2. 从该结果的高32位减去0x00180000。这非常快。
  3. 只要将任何浮点数乘以任何编译时常量整数(2的幂),就可以应用非常类似的优化。

    如果您将double除以,或者除以非编译时常量表达式(任何涉及final以外的任何表达式的表达式 - ,则此编译器优化不适用时间常数变量,文字数字或运算符)。在这种情况下,它必须作为双精度浮点除法执行,除了块传输和高级数学函数之外,它可能是最慢的单一操作

    但是,正如您所看到的,1<<24的编译时常量为2,因此优化 适用于此情况。

答案 1 :(得分:0)

将您的字节读入int(Java中总是32位),然后使用它。您需要double,而不是float,因为单精度浮点不一定足够长以保存32位定点数。

double toFixedPoint(int bytes){
    return bytes / Math.pow(2, 24);
}

如果速度是一个问题,那么在此方法之外计算Math.pow(2,24)并存储它。