【问题标题】:IBM to IEEE floating point convIBM 到 IEEE 浮点转换
【发布时间】:2021-07-01 21:53:53
【问题描述】:

在 java 中是否有任何标准方法可以将 IBM 370(以字节的形式)转换为 IEEE 格式?任何转换算法都会有所帮助..

我尝试编写 java 代码..但我不明白我哪里出错了。当我将输入作为 -2.000000000000000E+02 时,我得到的值是 IEEE 格式的 -140.0。在其他情况下,当我将输入作为 3.140000000000000E+00 时,我得到的值为 IEEE 格式的 3.1712502374909226 对此的任何帮助将不胜感激

private void conversion() {
    byte[] buffer = //bytes to be read(8 bytes);
    int sign = (buffer[0] & 0x80);
    // Extract exponent.
    int exp = ((buffer[0] & 0x7f) - 64) * 4 - 1;
    //Normalize the mantissa.
    for (int i = 0; i < 4; i++) {//since 4 bits per hex digit
        if ((buffer[1] & 0x80) == 0) {
            buffer = leftShift(buffer);
            exp = exp - 1;
        }
    }

    // Put sign and mantissa back in 8-byte number
    buffer = rightShift(buffer);// make room for longer exponent
    buffer = rightShift(buffer);
    buffer = rightShift(buffer);
    exp = exp + 1023;//Excess 1023 format
    int temp = exp & 0x0f;//Low 4 bits go into B(1)
    buffer[1]= (byte)((buffer[1]&0xf) | (temp *16));
    buffer[0]= (byte)(sign | ((exp/16) & 0x7f));
    }

     private byte[] rightShift(byte[] buf) {
    int newCarry = 0;
    int oldCarry = 0;
    for(int i = 1; i<buf.length; i++) {
        newCarry = buf[i] & 1;
        buf[i] = (byte)((buf[i] & 0xFE)/2 + (oldCarry != 0 ? 0x80 : 0));
        oldCarry = newCarry;
    }
    return buf;
}

private byte[] leftShift(byte[] buf) {
    int newCarry = 0;
    int oldCarry = 0;
    for(int i = buf.length-1; i>0; i--) {
        newCarry = buf[i] & 1;
        buf[i] = (byte)((buf[i] & 0x7F)*2 + (oldCarry != 0 ? 1 : 0));
        oldCarry = newCarry;
    }   
    return buf;
}

【问题讨论】:

标签: java floating-point ieee-754


【解决方案1】:

我可以看到几个不同的解决方案来解决您的问题:

【讨论】:

    【解决方案2】:

    IBM Technical Article 包含从 IBM 浮点格式转换为 IEE 浮点的算法。

    【讨论】:

      【解决方案3】:

      leftShift() 函数中存在一个错误,您应该使用 0x80 而不是 1 进行屏蔽。这是更正后的函数。

          private byte[] leftShift(byte[] buf) {
              int newCarry = 0;
              int oldCarry = 0;
              for(int i = buf.length-1; i>0; i--) {
                  newCarry = buf[i] & 0x80;
                  buf[i] = (byte)((buf[i] & 0x7F)*2 + (oldCarry != 0 ? 1 : 0));
                  oldCarry = newCarry;
              }
              return buf;
          }
      

      我使用wiki example -118.625 进行了测试,如果我理解正确,IBM double 的偏差也是 64,因此二进制文件将是 11000010 01110110 10100000 00000000 00000000 00000000 00000000 00000000。修复后,程序可以正确生成-118.625。

      我知道这是一个旧帖子,但我目前也遇到了同样的情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 2016-04-02
        相关资源
        最近更新 更多