如何将字节值转换为小数?

我正在尝试从文件中加载一些十进制值,但我无法找出正确的方法来获取原始值并将它们转换为小数。

我已经将文件读入一个字节数组,每个四个字节的块应该代表一个十进制值。 为了帮助解决这个问题,我构建了一个表,列出了十进制值1到46如何表示为四个字节的块。

例如,数字1显示为0,0,128,63,数字2显示为0,0,0,64,依此类推,最多为46,即0,0,56,66。 完整的表格可在此处获得 。

还有另一系列数字,它们分为三个小数位,包括负数,这是在这里 。

我所说的唯一文件

它们首先存储最低有效字节:1,256,65536,16777216。 这使hex序列01 01 00 00变为数字257(十进制)。 在C / C ++中,要读取例如一个浮点数,请执行:float x; fread(&x,sizeof(float),1,fileptr);

但是,我使用.NET的File.ReadAllBytes方法,所以这没有多大帮助。 如果有人可以花几分钟时间查看示例文件,看看他们是否能找到将值转换为小数的方法,我将非常感激。

您可以使用BitConverter.ToSingle从字节数组中读取浮点值,因此要获得一系列浮点数,您可以执行以下操作:

byte[] data = File.ReadAllBytes(fileName); int count = data.Length / 4; Debug.Assert(data.Length % 4 == 0); IEnumerable values = Enumerable.Range(0, count) .Select(i => BitConverter.ToSingle(data, i*4)); 

您是否考虑过使用BitConverter类? 它在字节数组和各种类型之间进行转换。

编辑: 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; } 

正如其他人所提到的,使用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 

.NET库在内部实现了Decimal.GetBytes()方法。

我使用反编译的.NET库在decimal和byte arrary之间创建一个简单的转换方法 – 你可以在这里找到它:

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

编辑:这是我链接的完整源代码。

 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; }