如何将两个字节转换为浮点数 [英] How to convert two bytes to floating point number
问题描述
我有一些需要挖掘数据的旧文件.这些文件是由Lotus123 Release 4 for DOS创建的.我试图通过解析字节而不是使用Lotus打开文件来更快地读取文件.
I have some legacy files that need mined for data. The files were created by Lotus123 Release 4 for DOS. I'm trying to read the files faster by parsing the bytes rather than using Lotus to open the files.
Dim fileBytes() As Byte = My.Computer.FileSystem.ReadAllBytes(fiPath)
'I loop through all the data getting first/second bytes for each value
do ...
Dim FirstByte As Int16 = Convert.ToInt16(fileBytes(Index))
Dim SecondByte As Int16 = Convert.ToInt16(fileBytes(Index + 1))
loop ...
我可以得到这样的整数值:
I can get integer values like this:
Dim value As Int16 = BitConverter.ToInt16(fileBytes, Index + 8) / 2
但是浮点数更加复杂.只有较小的数字存储有两个字节.较大的值占用10个字节,但这是另一个问题.在这里,我们只有两个字节的较小值.以下是一些示例值.我将字节值输入Excel,然后使用= DEC2BIN()转换为二进制,并根据需要在左侧添加零以获得8位.
But floating numbers are more complicated. Only the smaller numbers are stored with two bytes. Larger values take 10 bytes, but that's another question. Here we only have smaller values with two bytes. Here are some sample values. I entered the byte values into Excel and use the =DEC2BIN() to convert to binary adding zeros on the left as needed to get 8 bits.
First Second
Byte Byte Value First Byte 2nd Byte
7 241 = -1.2 0000 0111 1111 0001
254 255 = -1 1111 1110 1111 1111
9 156 = -0.8 0000 1001 1001 1100
9 181 = -0.6 0000 1001 1011 0101
9 206 = -0.4 0000 1001 1100 1110
9 231 = -0.2 0000 1001 1110 0111
13 0 = 0 0000 1101 0000 0000
137 12 = 0.1 1000 1001 0000 1100
9 25 = 0.2 0000 1001 0001 1001
137 37 = 0.3 1000 1001 0010 0101
9 50 = 0.4 0000 1001 0011 0010
15 2 = 0.5 0000 1111 0000 0010
9 75 = 0.6 0000 1001 0100 1011
137 87 = 0.7 1000 1001 0101 0111
9 100 = 0.8 0000 1001 0110 0100
137 112 = 0.9 1000 1001 0111 0000
2 0 = 1 0000 0010 0000 0000
199 13 = 1.1 1100 0111 0000 1101
7 15 = 1.2 0000 0111 0000 1111
71 16 = 1.3 0100 0111 0001 0000
135 17 = 1.4 1000 0111 0001 0001
15 6 = 1.5 0000 1111 0000 0110
7 20 = 1.6 0000 0111 0001 0100
71 21 = 1.7 0100 0111 0001 0101
135 22 = 1.8 1000 0111 0001 0110
199 23 = 1.9 1100 0111 0001 0111
4 0 = 2 0000 0100 0000 0000
我希望有一种简单的转换方法.否则可能会更复杂.
I'm hoping for a simple conversion method. Or maybe it'll be more complicated.
我查看了 BCD :"BCD用于许多早期的十进制计算机,并在诸如IBM System/360系列的机器指令集中实现"和英特尔BCD操作码
I looked at BCD: "BCD was used in many early decimal computers, and is implemented in the instruction set of machines such as the IBM System/360 series" and Intel BCD opcode
我不知道这是BCD还是什么.如何将两位转换为浮点数?
I do not know if this is BCD or what it is. How do I convert the two bits into a floating point number?
推荐答案
C
代码的VB.Net
转换发布由njuffa .
原始的structure
已替换为Byte数组,并且数值数据类型适用于.Net类型.就这样.
Just a VB.Net
translation of the C
code posted by njuffa.
The original structure
has been substituted with a Byte array and the numeric data type adapted to .Net types. That's all.
Dim data As Byte(,) = New Byte(,) {
{7, 241}, {254, 255}, {9, 156}, {9, 181}, {9, 206}, {9, 231}, {13, 0}, {137, 12}, {9, 25},
{137, 37}, {9, 50}, {15, 2}, {9, 75}, {137, 87}, {9, 100}, {137, 112}, {2, 0}, {199, 13},
{7, 15}, {71, 16}, {135, 17}, {15, 6}, {7, 20}, {71, 21}, {135, 22}, {199, 23}, {4, 0}
}
Dim byte1, byte2 As Byte
Dim word, code As UShort
Dim nValue As Integer
Dim result As Double
For i As Integer = 0 To (data.Length \ 2 - 1)
byte1 = data(i, 0)
byte2 = data(i, 1)
word = (byte2 * 256US) + byte1
If (word Mod 2) = 1 Then
code = (word \ 2US) Mod 8US
nValue = ((word \ 16) Xor 2048) - 2048
Select Case code
Case 0 : result = nValue * 5000
Case 1 : result = nValue * 500
Case 2 : result = nValue / 20
Case 3 : result = nValue / 200
Case 4 : result = nValue / 2000
Case 5 : result = nValue / 20000
Case 6 : result = nValue / 16
Case 7 : result = nValue / 64
End Select
Else
'unscaled 15-bit integer in h<15:1>. Extract, sign extend to 32 bits
nValue = ((word \ 2) Xor 16384) - 16384
result = nValue
End If
Console.WriteLine($"[{byte1,3:D}, {byte2,3:D}] number = {nValue:X8} result ={result,12:F8}")
Next
这篇关于如何将两个字节转换为浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!