【问题标题】:java - IBM-IEEE double-precision floating point byte conversionjava - IBM-IEEE 双精度浮点字节转换
【发布时间】:2016-06-23 22:56:42
【问题描述】:

我需要在 Java 中对字节数组进行 IBM-IEEE 浮点转换。我能够使用http://www.thecodingforums.com/threads/c-code-for-converting-ibm-370-floating-point-to-ieee-754.438469 成功地进行单精度浮点字节的转换。

但我还需要转换双精度双精度的字节。我所看到的所有地方似乎都只显示单精度转换。我得到的最接近的是http://spdf.sci.gsfc.nasa.gov/pub/documents/old/miscellaeous_documents_from_nssdc/b46645.txt 中的 r8ibmieee 函数,但它使用 C 联合/位域并且仅将 IBM 转换为 IEEE(而不是相反)。我希望有一个类似于第一个链接的解决方案,它采用字节数组或十六进制字符串并输出字节数组或十六进制字符串。有没有人有一种算法可以将双精度字节从 IBM 转换为 IEEE,反之亦然,并且可以在 Java 中运行?

【问题讨论】:

    标签: java floating-point bytearray ieee-754


    【解决方案1】:

    我从未见过,但我会在查看格式后尝试。 (https://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture#Double-precision_64-bit;https://en.wikipedia.org/wiki/Double-precision_floating-point_format)

    我建议您使用long(64 位整数)值;这会容易得多。您将字节数组转换为long,使用它转换浮点格式,然后将生成的long 转换回字节数组。我不会告诉你如何在long 和字节数组值之间进行转换,因为我不知道你的字节数组是小端还是大端。

    IBM 64 位浮点数的格式为

    1  sign bit
    7  exponent bits (power of 16), bias = 64
    56  mantissa bits
    

    如果指数是X,尾数位是bbbbb...bbbbb,那么浮点数(如果符号位为0)的值为16^(X em>-64) * 0.bbbbb...bbbbb.

    IEEE 754 64 位浮点数的格式为

    1   sign bit
    11  exponent bits (power of 2), bias = 1023
    52  mantissa bits, with an implied a bit
    

    若指数为X且尾数位为bbbbb...bbbbb,则浮点数(若符号位为0)的值为2^(X-1023) * 1.bbbbb...bbbbb。

    所以现在您需要弄清楚如何以 IEEE 格式表示相同的值(尽可能接近;您可能会丢失一些精度,因为 IBM 尾数更长)。

    1. 两种格式的符号位相同。

    2. 计算 IEEE 指数的初始值:如果 IBM 指数是 X1,而 IEEE 指数是 X 2,我们需要找到 X2 使得 16^(X1 >-64) = 2^(X2-1023)。左边将等于 2^(4*X1-256),所以由于 2 的幂必须相同,这给了我们 X 2 = 4*X1-256+1023 = 4*X1+767。

    3. 此时如果IBM float的尾数为bbbbb...bbbbb,则浮点值为sign * 2^(X2-1023) * 0.bbbbb...bbbbb。但是,对于 IEEE 浮点数,我们必须安排尾数位,以便乘以 1.bbbbb...bbbbb。这意味着我们需要移动 IBM 尾数的尾数位,直到我们将 1 移到二进制点左侧的位。每次我们移动尾数时,我们将它加倍,这意味着我们必须通过从 X2 中减去 1 来进行补偿。因此,假设在第 2 步之后,我们有 X2=1031 并且尾数 = 0011 0111 1100 ...我们代表的数字是 28 * 0.001101111100 ..... 我们需要将尾数左移 3 位,以将 1 移到二进制点的左位;因此,该数字等于 25 * 1.101111100.... 因此,此步骤之后的 X2 将为 1031 - 3 = 1028;这就是将进入 IEEE 浮点数的指数字段的值。

    二进制点左边的 1 不进入 IEEE 浮点数。这是一个“隐含的 1”。 IEEE 浮点数的尾数位将是 101111100..... 注意 IBM 尾数有 56 位;你剩下的值,不计算隐含的 1,仍然有 56 位。您需要切掉低 4 位以将 IEEE 浮点数降至 52,并且您可能需要舍入。

    在这一切之后,您现在有了符号位、指数字段 (X2) 以及构建 64 位 IEEE 浮点数所需的尾数位.

    【讨论】:

    • 我将如何做相反的事情?
    • 我希望我提供了足够的信息,您可以弄清楚那部分。我愿意免费做的工作是有限度的。
    • 我可以看到如何做几乎所有的事情,有一部分暗示我正在撤消标准化,我们怎么知道尾数右移多远?
    • 在上面的#2中,我说X2 = 4 * X1 + 767,这意味着X2 - 767 = 4 * X1。如果 X2 - 767 不是 4 的倍数,则需要将尾数向右移动(在左侧引入前导 0)。每次将尾数向右移动时,都会通过在 X2 上加 1 来补偿(与我在步骤 3 中所说的相反)。这样做直到 X2 - 767 是 4 的倍数。或者计算出需要添加到 X2 多少才能使 X2 - 767 成为 4 的倍数,然后右移那么多位。您最多可以右移 3 位。
    猜你喜欢
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2013-07-24
    • 2015-06-12
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多