Формат single IBM float point преобразование в Csharp Single(float) формат - C#

Узнай цену своей работы

Формулировка задачи:

Возникла проблема с чтением данных в формате IBM float point. Пытался найти какой-либо простой метод преобразования во внутренний форма CSharp, не вышло. Начал побайтно разбирать его, прочитал википедию. Там все просто: SEF : S EEEEEEE FFFFFFFF FFFFFFFF FFFFFFFF bits : 1 2 8 9 32 bytes : byte1 byte2 byte3 byte4 Первый бит - знак, потом экспонента(2-8 биты) и некий "Fractoin"- если, кто объяснит, как он на русском называется буду благодарен. Написал код:
public static float IBMEncoding(byte[] bInputBytes)
        {
            //Method of conversation from IBM Float point to Csharp single format.
            float fOutput = 0; //результат
            int A = 16;      // Постоянный для IBM float множетиль
            int B = 64;     // Константа степени.
            double dFraction = 0;   // тот самый fraction= 1/2+1/4+...+(1/2)^n;
            int iExp = 0; // экспонентаю
            int iSign;  //знак
            int[] b = new int[32];
            
            #region Bit2Int // проблемы начались с самого начала данные в BigEndian формате Csharp упорно хотел LittleEndian 
                                   // пришлось разворачивать. К тому же использование массива int мне показалось более удобным в 
                                   // сравнении с использоавнием битных шифтов и прочих радостей вычлинения битов из байта.
            for (int j = 0; j < bInputBytes.Length; j++)
            {
                for (int i = 0; i < 8; i++)
                {
                    b[31 - (j * 8 + i)] = bInputBytes[j] >> i & 0x1; ;
                   ;
                };
            };
            #endregion
 
            iSign = Convert.ToInt32(Math.Pow(-1 , b[0])); // Получил знак собстевнно из первого бита.
                    
            for (int i = 1; i < 8; i++) //Получаю значение экспоненты
            {
               iExp = Convert.ToInt32(iExp + Math.Pow(2, i-1) * b[8-i]); // Это место мне совершенно не понятно, может кто уточнит
                                                                                                        // Я использую обратный порядок для получения
                                                                                                       // экспоненты т.е. самые большие значения у меня слева.
                                                                                                       // Это единственный способ получения нужного результат
                                                                                                       // Если кто понимает в этом может объяснить как так?
            };
            for (int i = 8; i < 32; i++) // Fraction 
            {
                dFraction = dFraction + Math.Pow(0.5, i-8)*b[i]; //Получаю Fraction его уже не разворачиваю
            };
            fOutput = Convert.ToSingle( iSign*dFraction*Math.Pow(A,(iExp-B))); // Все вставляю в окончательную формулу 
                                                                                                                    //  и получаю искомое значение (проверено сторонним софтом)
           
            return fOutput;
        }
1.Если у кого были подобные трудности, может поделитись опытом и объяснити странные повороты туда-сюда. 2. Может у кого-нибудь есть идеи оптимизации, слошком много циклов на мой взгляд.

Решение задачи: «Формат single IBM float point преобразование в Csharp Single(float) формат»

textual
Листинг программы
float ibm = -157.1817f;
 
var raw       = *(int*)&ibm;
var sign      = raw >> 31 & 0x01;
var exponent  = raw >> 24 & 0x7f;
var mantissa  = (raw & 0x00ffffff) / (float)(1 << 24);
var ieeeFloat = (1 - 2 * sign) * mantissa * (float)Math.Pow(16, exponent - 64);

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.429 из 5