【问题标题】:Convert from IBM floating point to IEEE floating point standard and Vice Versa- In C#?从 IBM 浮点转换为 IEEE 浮点标准和副 Versa- 在 C# 中?
【发布时间】:2010-12-28 23:28:22
【问题描述】:

正在为我们正在使用的旧系统寻找一种将 IEEE 浮点数转换为 IBM 浮点格式的方法。

是否有一个通用的公式可以在 C# 中使用。

【问题讨论】:

    标签: c# c floating-point ieee-754


    【解决方案1】:
    // http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture
    // float2ibm(-118.625F) == 0xC276A000
    // 1 100 0010    0111 0110 1010 0000 0000 0000
    // IBM/370 single precision, 4 bytes
    // xxxx.xxxx xxxx.xxxx xxxx.xxxx xxxx.xxxx
    // s|-exp--| |--------fraction-----------|
    //    (7)          (24)
    // value = (-1)**s * 16**(e - 64) * .f   range = 5E-79 ... 7E+75
    static int float2ibm(float from)
    {
        byte[] bytes = BitConverter.GetBytes(from);
        int fconv = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8)| bytes[0];
    
        if (fconv == 0) return 0;
        int fmant = (0x007fffff & fconv) | 0x00800000;
        int t = (int)((0x7f800000 & fconv) >> 23) - 126;
        while (0 != (t & 0x3)) { ++t; fmant >>= 1; }
        fconv = (int)(0x80000000 & fconv) | (((t >> 2) + 64) << 24) | fmant;
        return fconv; // big endian order
    }
    

    我更改了一段名为 static void float_to_ibm(int from[], int to[], int n, int endian) 的代码 上面的代码可以在PC上正确运行 from 是小端浮点数。 返回值是大端ibm浮点数,但存储在int类型中。

    【讨论】:

    • 这真的救了我的命,我希望我能奖励你们 50 点声望点给你们超速和 Noam M,我只是不知道如何。注意:在我的情况下,我必须以相反的顺序读取返回的 int 的字节,才能将可打印的输出输出到 windows-1252 编码文件(小端)。它是为 SAS XPORT 设计的。
    • 如果我能很好地理解这一点并将其扩展到 64 位双打,我会很高兴的。此实现出自哪个文档?
    • IEEE-754 float 支持 -0:我认为这个值没有被正确处理。将第一个检查更改为 ((fconv &amp; 0x7fffffff) == 0) 应该可以解决该问题。由于 IBM 浮点格式也确实支持负 0,因此可以将符号位添加回来,但 IBM 浮点算法似乎不会保持负 0。
    【解决方案2】:

    一个明显的方法是使用数字的文本表示作为交换格式。

    【讨论】:

    • @mekrizzy 因为两个系统都可以将浮点数转换为文本,您可以将文本用作您的通用语言。
    【解决方案3】:

    我最近不得不将一个浮点数转换为另一个浮点数。看起来 XDR 格式的浮点数使用了一种奇怪的格式。所以当从 XDR 转换为标准浮点数时,这段代码就做到了。

    #include <rpc/rpc.h>
    
    // Read in XDR float array, copy to standard float array
    // out array needs to be allocated before the function call
    
    bool convertFromXdrFloatArray(float *in, float *out, long size)
    {
        XDR xdrs;
        xdrmem_create(&xdrs,(char *)in, size*sizeof(float), XDR_DECODE);
    
        for(int i = 0; i < size; i++)
        {
            if(!xdr_float(&xdrs, out++)) {
                fprintf(stderr,"%s:%d:ERROR:xdr_float\n",__FILE__,__LINE__);
                exit(1);
            }
        }
        xdr_destroy(&xdrs);
    
        return true;
    }
    

    【讨论】:

      【解决方案4】:

      使用第一个答案,我添加了以下在某些情况下可能有用的内容:

      ///

        /// Converts an IEEE floating number to its string representation (4 or 8 ascii codes).
          /// Useful for SAS XPORT files format.
          /// </summary>
          /// <param name="from_">IEEE number</param>
          /// <param name="padTo8_">When true, output is 8 chars rather than 4</param>
          /// <returns>Printable string according to hardware's endianness</returns>
          public static string Float2IbmAsAsciiCodes(float from_, bool padTo8_ = true)
          {
              StringBuilder sb = new StringBuilder();
              string s;
              byte[] bytes = BitConverter.GetBytes(Float2Ibm(from_)); // big endian order
      
              if (BitConverter.IsLittleEndian)
              {
                  // Revert bytes order
                  for (int i = 3; i > -1; i--)
                      sb.Append(Convert.ToChar(bytes[i]));
                  s = sb.ToString();
                  if (padTo8_)
                      s = s.PadRight(8, '\0');
                  return s;
              }
              else
              {
                  for (int i = 0; i < 8; i++)
                      sb.Append(Convert.ToChar(bytes[i]));
                  s = sb.ToString();
                  if (padTo8_)
                      s = s.PadRight(8, '\0');
                  return s;
              }
          }
      

      【讨论】:

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