2010-08-12 2 views
4

Я пытаюсь загрузить некоторые десятичные значения из файла, но я не могу правильно определить исходные значения и преобразовать их в десятичные числа.Как преобразовать значения байтов в десятичные числа?

Я прочитал файл в массив байтов, и каждый фрагмент из четырех байтов должен представлять одно десятичное значение. Чтобы понять это, я построил таблицу того, как десятичные значения от 1 до 46 представлены в виде четырех байтовых блоков.

Например, номер 1 отображается как 0,0128,63, номер 2 - 0,0,0,64 и т. Д. До 46, что составляет 0,0,56,66. Полная таблица доступна here.

Существует также другая серия чисел, которые идут до трех знаков после запятой и включают в себя негативы, которые являются here.

Единственная документация у меня есть состояния

Они хранятся не менее значащий байт первым: 1-х, 256-х, 65536-х, 16777216 лет. Это делает шестнадцатеричную последовательность 01 01 00 00 в число 257 (десятичная). В C/C++, чтобы читать, например. float, do: float x; fread (& x, sizeof (float), 1, fileptr);

Однако я использую метод .NET File.ReadAllBytes, поэтому это не очень помогает. Если кто-то может сэкономить несколько минут, чтобы посмотреть файлы примеров и посмотреть, смогут ли они определить способ преобразования значений в десятичные знаки, я был бы очень благодарен.

ответ

3

Вы можете использовать BitConverter.ToSingle для считывания значения с плавающей точкой из массива байтов, поэтому, чтобы получить последовательность поплавков , вы могли бы сделать что-то вроде этого:

byte[] data = File.ReadAllBytes(fileName); 
int count = data.Length/4; 
Debug.Assert(data.Length % 4 == 0); 

IEnumerable<float> values = Enumerable.Range(0, count) 
    .Select(i => BitConverter.ToSingle(data, i*4)); 
+0

Я отметил это правильно, поскольку он немного более подробно. Большое спасибо, не ожидал, что это будет так просто. – gilles27

2

Вы изучали использование класса BitConverter? Он преобразует байтовые массивы и различные типы.

Edit: MSDN имеет полезный комментарий к документации BitConverter на http://msdn.microsoft.com/en-us/library/system.bitconverter_methods(v=vs.85).aspx:

public static decimal ToDecimal(byte[] bytes) 
{ 
    int[] bits = new int[4]; 
    bits[0] = ((bytes[0] | (bytes[1] << 8)) | (bytes[2] << 0x10)) | (bytes[3] << 0x18); //lo 
    bits[1] = ((bytes[4] | (bytes[5] << 8)) | (bytes[6] << 0x10)) | (bytes[7] << 0x18); //mid 
    bits[2] = ((bytes[8] | (bytes[9] << 8)) | (bytes[10] << 0x10)) | (bytes[11] << 0x18); //hi 
    bits[3] = ((bytes[12] | (bytes[13] << 8)) | (bytes[14] << 0x10)) | (bytes[15] << 0x18); //flags 

    return new decimal(bits); 
} 

public static byte[] GetBytes(decimal d) 
{ 
    byte[] bytes = new byte[16]; 

    int[] bits = decimal.GetBits(d); 
    int lo = bits[0]; 
    int mid = bits[1]; 
    int hi = bits[2]; 
    int flags = bits[3]; 

    bytes[0] = (byte)lo; 
    bytes[1] = (byte)(lo >> 8); 
    bytes[2] = (byte)(lo >> 0x10); 
    bytes[3] = (byte)(lo >> 0x18); 
    bytes[4] = (byte)mid; 
    bytes[5] = (byte)(mid >> 8); 
    bytes[6] = (byte)(mid >> 0x10); 
    bytes[7] = (byte)(mid >> 0x18); 
    bytes[8] = (byte)hi; 
    bytes[9] = (byte)(hi >> 8); 
    bytes[10] = (byte)(hi >> 0x10); 
    bytes[11] = (byte)(hi >> 0x18); 
    bytes[12] = (byte)flags; 
    bytes[13] = (byte)(flags >> 8); 
    bytes[14] = (byte)(flags >> 0x10); 
    bytes[15] = (byte)(flags >> 0x18); 

    return bytes; 
} 
+0

Спасибо, что это определенно путь. – gilles27

+0

К сожалению, он не использует десятичное преобразование. –

+0

@EranBetzalel MSDN имеет некоторый код для реализации «отсутствующих» элементов BitConverter. См. Измененное обновление. – BlueMonkMN

0

Как уже упоминалось, использовать BitConverter класс, смотрите пример ниже:

 byte[] bytez = new byte[] { 0x00, 0x00, 0x80, 0x3F }; 
    float flt = BitConverter.ToSingle(bytez, 0); // 1.0 

    bytez = new byte[] { 0x00, 0x00, 0x00, 0x40 }; 
    flt = BitConverter.ToSingle(bytez, 0); // 2.0 

    bytez = new byte[] { 0, 0, 192, 190 }; 
    flt = BitConverter.ToSingle(bytez, 0); // -0.375 
0

Библиотека .NET реализована методом Decimal.GetBytes() внутри.

Я использовал декомпилированный библиотеки .NET для создания простых методов преобразования между десятичной и байт arrary - вы можете найти его здесь:

https://gist.github.com/eranbetzalel/5384006#file-decimalbytesconvertor-cs

EDIT: Вот полный исходный код из моей ссылки.

public decimal BytesToDecimal(byte[] buffer, int offset = 0) 
{ 
    var decimalBits = new int[4]; 

    decimalBits[0] = buffer[offset + 0] | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24); 
    decimalBits[1] = buffer[offset + 4] | (buffer[offset + 5] << 8) | (buffer[offset + 6] << 16) | (buffer[offset + 7] << 24); 
    decimalBits[2] = buffer[offset + 8] | (buffer[offset + 9] << 8) | (buffer[offset + 10] << 16) | (buffer[offset + 11] << 24); 
    decimalBits[3] = buffer[offset + 12] | (buffer[offset + 13] << 8) | (buffer[offset + 14] << 16) | (buffer[offset + 15] << 24); 

    return new Decimal(decimalBits); 
} 

public byte[] DecimalToBytes(decimal number) 
{ 
    var decimalBuffer = new byte[16]; 

    var decimalBits = Decimal.GetBits(number); 

    var lo = decimalBits.Value[0]; 
    var mid = decimalBits.Value[1]; 
    var hi = decimalBits.Value[2]; 
    var flags = decimalBits.Value[3]; 

    decimalBuffer[0] = (byte)lo; 
    decimalBuffer[1] = (byte)(lo >> 8); 
    decimalBuffer[2] = (byte)(lo >> 16); 
    decimalBuffer[3] = (byte)(lo >> 24); 

    decimalBuffer[4] = (byte)mid; 
    decimalBuffer[5] = (byte)(mid >> 8); 
    decimalBuffer[6] = (byte)(mid >> 16); 
    decimalBuffer[7] = (byte)(mid >> 24); 

    decimalBuffer[8] = (byte)hi; 
    decimalBuffer[9] = (byte)(hi >> 8); 
    decimalBuffer[10] = (byte)(hi >> 16); 
    decimalBuffer[11] = (byte)(hi >> 24); 

    decimalBuffer[12] = (byte)flags; 
    decimalBuffer[13] = (byte)(flags >> 8); 
    decimalBuffer[14] = (byte)(flags >> 16); 
    decimalBuffer[15] = (byte)(flags >> 24); 

    return decimalBuffer; 
} 
Смежные вопросы