Преобразовать из IBM с плавающей точкой в ​​стандарт IEEE с плавающей точкой и наоборот в C #? - PullRequest
5 голосов
/ 29 декабря 2010

Искал способ перевести числа IEEE с плавающей запятой в формат IBM с плавающей запятой для старой системы, которую мы используем.

Существует ли общая формула, которую мы можем использовать в C # для этой цели.

Ответы [ 4 ]

6 голосов
/ 24 октября 2013
// 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 из [], int в [], int n, int endian) приведенный выше код можно правильно запустить на ПК из - это число с прямым порядком байтов. возвращаемое значение - это число с плавающей точкой с прямым порядком байтов, но оно хранится в типе int.

2 голосов
/ 29 декабря 2010

Очевидным подходом было бы использование текстового представления числа в качестве формата обмена.

0 голосов
/ 24 августа 2017

Используя первый ответ, я добавил следующее, что может быть полезно в некоторых случаях:

///

  /// 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;
        }
    }
0 голосов
/ 19 мая 2017

Мне недавно пришлось конвертировать один поплавок в другой.Похоже, формат XDR использует странный формат для своих операций с плавающей точкой.Поэтому при преобразовании из XDR в стандартные числа с плавающей запятой этот код сделал это.

...