📄 如何从二进制文件读取 ibm 370 数据.htm
字号:
<H3 id=tocHeadRef>整数转换</H3>
<SCRIPT
type=text/javascript>loadTOCNode(2, 'moreinformation');</SCRIPT>
只不过是相反的字节顺序 2 个字节和 4 字节整数格式等同于 VisualBasic 中 Integer 和 Long 数据类型。
因此, 整数, VisualBasic 中 A47C 十六进制值将存储作为 7CA4。 下列例程交换的 2 个字节和 4
字节整数字节顺序。 这些例程利用 LSet 语句, 只要大小是相同允许作业之间不同结构的数据: <CODE><PRE class=code>Private Type MungeInteger
Value As Integer
End Type
Private Type MungeLong
Value As Long
End Type
Private Type Munge2Bytes
Bytes(0 To 1) As Byte
End Type
Private Type Munge4Bytes
Bytes(0 To 3) As Byte
End Type
Private Sub SwapBytes(B() As Byte)
'
' Reverses the order of the bytes in the array.
'
Dim I As Long, Temp As Byte, Offset As Long
Offset = LBound(B) + UBound(B)
For I = LBound(B) To UBound(B) \ 2
Temp = B(I)
B(I) = B(Offset - I)
B(Offset - I) = Temp
Next I
End Sub
Public Function IBMToVBAInteger(ByVal IBM_Value As Integer) As Integer
'
' Converts an Integer in IBM 370 format to IEEE format
' by reversing the order of the bytes.
'
Dim iTemp As MungeInteger, bTemp As Munge2Bytes
iTemp.Value = IBM_Value
LSet bTemp = iTemp
SwapBytes bTemp.Bytes
LSet iTemp = bTemp
IBMToVBAInteger = iTemp.Value
End Function
Public Function IBMToVBALong(ByVal IBM_Value As Long) As Long
'
' Converts a Long in IBM 370 format to IEEE format
' by reversing the order of the bytes.
'
Dim lTemp As MungeLong, bTemp As Munge4Bytes
lTemp.Value = IBM_Value
LSet bTemp = lTemp
SwapBytes bTemp.Bytes
LSet lTemp = bTemp
IBMToVBALong = lTemp.Value
End Function
</PRE></CODE>获得数据后, 可以传递字段通过 IBMToVBAInteger 和 IBMToVBALong
函数来执行转换。
<P class=topOfPage><A
href="http://support.microsoft.com/kb/235856/zh-cn#top"><IMG alt=""
src="如何从二进制文件读取 IBM 370 数据.files/uparrow.gif">回到顶端</A></P>
<H3 id=tocHeadRef>IBM 370 和 IEEE 浮点格式</H3>
<SCRIPT
type=text/javascript>loadTOCNode(2, 'moreinformation');</SCRIPT>
只是 8 字节浮点数字的一个其他 32 位尾数中 IBM 4 个字节和 8 字节浮点格式是相同。 由于这个原因, 4
字节浮点格式有时称为截断浮点数。 IBM 370 浮点格式是如下: <BR><BR>
<TABLE class=table cellSpacing=1>
<TBODY>
<TR>
<TH>位</TH>
<TH>说明</TH></TR>
<TR>
<TD>0</TD>
<TD>符号位。 0 正数 ; 1 表示负数。</TD></TR>
<TR>
<TD>1 - 7</TD>
<TD>Exponent。 这是以多余 64 格式, 意味着数字范围 0 - 127 表示的指数值是 - 64 到 +63
存储。 指数是基 16。</TD></TR>
<TR>
<TD>8 - 31 (4 字节) 或<BR>(8 字节) 8 - 63。</TD>
<TD>Mantissa。 这是小数值与 0.0625 0.999 …, 其中乘以 16 ^ Exponent 给予值数。
如果所有 32 或 64 位是 0, 数为零。</TD></TR></TBODY></TABLE><BR><BR>IEEE
浮点如下所示: <BR><BR>
<TABLE class=table cellSpacing=1>
<TBODY>
<TR>
<TH>位</TH>
<TH>说明</TH></TR>
<TR>
<TD>0</TD>
<TD>符号位。 0 正数 ; 1 表示负数。</TD></TR>
<TR>
<TD>1 - 8 (4 字节) 或<BR>1 - 11 (8 字节)</TD>
<TD>Exponent。 这是存储在多余 127 格式 (4 字节) 或多余 1023 format(8-byte),
意味着数字范围 2047 0 - 0 - 255 (或) 表示的指数值是 -127 到 +128 (或 - 1023 到
+1024)。 指数是基二。</TD></TR>
<TR>
<TD>9 - 31 (4 字节) 或<BR>(8 字节) 12 - 63。</TD>
<TD>Mantissa。 数字 1 添加到此分数, …, 1.0 到 1.999 范围中提供值其中乘以 2 ^
Exponent 给予值数。 如果所有 32 或 64 位是 0, 然后数为零。</TD></TR></TBODY></TABLE>
<P class=topOfPage><A
href="http://support.microsoft.com/kb/235856/zh-cn#top"><IMG alt=""
src="如何从二进制文件读取 IBM 370 数据.files/uparrow.gif">回到顶端</A></P>
<H3 id=tocHeadRef>浮点转换</H3>
<SCRIPT
type=text/javascript>loadTOCNode(2, 'moreinformation');</SCRIPT>
对浮点数字转换例程涉及下列步骤:<BR><BR>
<TABLE class="list ol">
<TBODY>
<TR>
<TD class=number>1.</TD>
<TD class=text>提取标志位和 Exponent 位值。 将 Exponent 值从 IBM 格式转换为
IEEE 格式:
<TABLE class="list ol">
<TBODY>
<TR>
<TD class=number>1.</TD>
<TD class=text>减去 64 通过 4 来删除 " Excess 64 "
offset.Multiply 由于它是基 16 并且 IEEE 数字使用基础 Subtract 1 . 因为
IEEE 尾数处于范围 1 到 2 而 0.5 到 1。</TD></TR>
<TR>
<TD class=number>2.</TD>
<TD class=text>因为 IEEE 尾数处于范围 1 到 2 而 0.5 到 1 多次由 4
因为它是基 16 和 IEEE 数字使用基 . Subtract 1。</TD></TR>
<TR>
<TD class=number>3.</TD>
<TD class=text>因为 IEEE 尾数处于范围 1 到 2 而 0.5 到 1 减去
1。</TD></TR></TBODY></TABLE>因为指数是以 IBM 格式, 基 16 尾数可能高位顺序字节, 值为
0。 因此您需要移动尾数左边, 直到高位为 1 递减指数 IEEE 格式对于此禁用规范化号码, 中。 用 0 填充低顺序位。
添加 127 或到 1023 - 4 字节和 8 字节 Exponent 值分别将 IEEE 偏移。 将标记并
Exponent 位备份号码中。 反转的字节顺序。 </TD></TR>
<TR>
<TD class=number>2.</TD>
<TD class=text>将 Exponent 值从 IBM 格式转换为 IEEE 格式:
<TABLE class="list ol">
<TBODY>
<TR>
<TD class=number>1.</TD>
<TD class=text>减去 64 通过 4 来删除 " Excess 64 "
offset.Multiply 由于它是基 16 并且 IEEE 数字使用基础 Subtract 1 . 因为
IEEE 尾数处于范围 1 到 2 而 0.5 到 1。</TD></TR>
<TR>
<TD class=number>2.</TD>
<TD class=text>因为 IEEE 尾数处于范围 1 到 2 而 0.5 到 1 多次由 4
因为它是基 16 和 IEEE 数字使用基 . Subtract 1。</TD></TR>
<TR>
<TD class=number>3.</TD>
<TD class=text>因为 IEEE 尾数处于范围 1 到 2 而 0.5 到 1 减去
1。</TD></TR></TBODY></TABLE>因为指数是以 IBM 格式, 基 16 尾数可能高位顺序字节, 值为
0。 因此您需要移动尾数左边, 直到高位为 1 递减指数 IEEE 格式对于此禁用规范化号码, 中。 用 0 填充低顺序位。
添加 127 或到 1023 - 4 字节和 8 字节 Exponent 值分别将 IEEE 偏移。 将标记并
Exponent 位备份号码中。 反转的字节顺序。 </TD></TR>
<TR>
<TD class=number>3.</TD>
<TD class=text>因为指数是以 IBM 格式, 基 16 尾数可能高位顺序字节, 值为 0。
因此您需要移动尾数左边, 直到高位为 1 递减指数 IEEE 格式对于此禁用规范化号码, 中。 用 0 填充低顺序位。 添加
127 或到 1023 - 4 字节和 8 字节 Exponent 值分别将 IEEE 偏移。 将标记并 Exponent
位备份号码中。 反转的字节顺序。 </TD></TR>
<TR>
<TD class=number>4.</TD>
<TD class=text>添加 127 或到 1023 - 4 字节和 8 字节 Exponent 值分别将 IEEE
偏移。 将标记并 Exponent 位备份号码中。 反转的字节顺序。 </TD></TR>
<TR>
<TD class=number>5.</TD>
<TD class=text>将标记并 Exponent 位备份号码中。 反转的字节顺序。 </TD></TR>
<TR>
<TD class=number>6.</TD>
<TD class=text>反转的字节顺序。
</TD></TR></TBODY></TABLE>对用于交换字节前面文章中给定代码生成以下例程: <CODE><PRE class=code>Private Type MungeSingle
A As Single
End Type
Private Type MungeDouble
A As Double
End Type
Private Type Munge8Bytes
B(0 To 7) As Byte
End Type
Public Function IBMToVBASingle(ByVal IBM_Value As Single) As Single
'
' Converts a Single in IBM 370 format to IEEE format.
'
Dim sTemp As MungeSingle, bTemp As Munge4Bytes
sTemp.Value = IBM_Value
LSet bTemp = sTemp
IBM370_To_IEEE bTemp.Bytes
SwapBytes bTemp.Bytes
LSet sTemp = bTemp
IBMToVBASingle = sTemp.Value
End Function
Public Function IBMToVBADouble(ByVal IBM_Value As Double) As Double
'
' Converts a Double in IBM 370 format to IEEE format
'
Dim dTemp As MungeDouble, bTemp As Munge8Bytes
dTemp.Value = IBM_Value
LSet bTemp = dTemp
IBM370_To_IEEE bTemp.Bytes
SwapBytes bTemp.Bytes
LSet dTemp = bTemp
IBMToVBADouble = dTemp.Value
End Function
Private Sub ShiftLeft(B() As Byte)
'
' Shifts all bits in the array 1 to the Left.
' Doesn't shift B(0) because it doesn't contain the mantissa.
'
Dim I As Long, MaxItem As Long, NewCarry As Long, OldCarry As Long
MaxItem = UBound(B)
For I = MaxItem To 1 Step -1
NewCarry = B(I) And &H80
B(I) = (B(I) And &H7F) * 2 + IIf(OldCarry, 1, 0)
OldCarry = NewCarry
Next I
End Sub
Private Sub ShiftRight(B() As Byte)
'
' Shifts all bits in the array 1 to the Right.
' Doesn't shift B(0) because it doesn't contain the mantissa.
'
Dim I As Long, MaxItem As Long, NewCarry As Long, OldCarry As Long
MaxItem = UBound(B)
For I = 1 To MaxItem
NewCarry = B(I) And 1
B(I) = (B(I) And &HFE) \ 2 + IIf(OldCarry, &H80, 0)
OldCarry = NewCarry
Next I
End Sub
Private Sub IBM370_To_IEEE(B() As Byte)
'
' This routine is the heart of the conversion.
'
Dim Sign As Long, Exponent As Long, I As Long, Temp As Long
'
' Extract sign.
'
Sign = B(0) And &H80
'
' Extract exponent.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -