我需要阅读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
答案 0 :(得分:2)
根据David Wallace的回答中的一些讨论,可以更快地计算出正确的double
。
转换它的最快方法可能是这样的:
double intFixedPoint24ToDouble(int bits){
return ((double) bits) / 1<<24;
}
原因这个更快是因为双精度浮点算术的工作方式。在这种情况下,上述序列可以转换为一些非常简单的加法和位移。当它运行时,它采取的实际步骤如下所示:
int
(bits
)转换为double
(通常在FPU上完成)。这很快。0x00180000
。这非常快。只要将任何浮点数乘以任何编译时常量整数(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)
并存储它。