在java中转换80位扩展精度

时间:2016-02-27 11:59:23

标签: java type-conversion extended-precision

我正在开发一个将旧的Open Access 4 .df文件转换为的程序 其他格式,也创建数据库脚本 - 我已经能够转换每一个 除十进制类型外的可能类型。我发现字节顺序必须是80位扩展精度。我已经尝试自己进行转换,但是我无法在Java中将80位扩展精度(https://en.wikipedia.org/wiki/Extended_precision#x86_Extended_Precision_Format)转换为String和String到80位扩展精度。

  1. 示例:
  2. 价值:1,235

    来自df文件的十六进制文件:40 00 9e 06 52 14 1e f0 db f6

    1. 示例:
    2. 价值:0,750

      来自df的十六进制文件:3f ff c0 00 00 00 00 00 00 00

      也许有人可以帮助转换?

      祝你好运

      @EJP评论: 好的,我扔掉了最后的16位所以我得到3f ff c0 00 00 00 00 00关于(Java - Convert hex to IEEE-754 64-bit float - double precision)我尝试用

      转换它
      {{1}}

      但结果是1,984375而不是0,750

1 个答案:

答案 0 :(得分:3)

我不确定它是否有资格作为答案或是否可以回答,因为......你确定它是标准的80位浮点格式吗?因为它确实看起来有点奇怪。举个例子:

40 00 9e ...

这里,0x4000-16383 = 1是指数。尾数以MSB 1开头,它对应于整数部分,因此它的形式应为1,... x 2 ^ 1,大于2.但是你应该说它应该是1,235。没有意义。

我在Java中创建了这个丑陋的黑客,它组合了双重的东西:

long high = 0x40_00L;
long low = 0x9e_06_52_14_1e_f0_db_f6L;
long e = (((high & 0x7FFFL) - 16383) + 1023) & 0x7FFL;
long ld = ((high & 0x8000L) << 48)
          | (e << 52)
          | ((low >>> 11) & 0xF_FFFF_FFFF_FFFFL);
System.out.printf("%16X\n", ld);
double d = Double.longBitsToDouble(ld);
System.out.println(d);

假设输入是正确的80位值,此片段应该正常工作,除非它没有正确舍入,不检查溢出,不处理非标准化值并且可能无法处理像NaN这样的特殊值。对于此输入,它打印

4003C0CA4283DE1B
2.46913578

不是1,235!然后我使用了这个C ++代码(用GCC编译,其中long double是80位格式):

#include <stdio.h>

int main() {
    long long high = 0x4000;
    long long low = 0x9e0652141ef0dbf6;
    long double d;
    char *pd = (char*)&d, *ph = (char*)&high, *pl = (char*)&low;
    for (int i = 0; i < 8; ++i) {
        pd[i] = pl[i];
    }
    for (int i = 0; i < 2; ++i) {
        pd[8 + i] = ph[i];
    }
    printf("%lf\n", (double) d);
}

它还打印2.469136。