[译]在IEEE,IBM或VAX浮点数格式和字节表达式之间转换
By robot-v1.0
本文链接 https://www.kyfws.com/applications/transform-between-ieee-ibm-or-vax-floating-point-n-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 9 分钟阅读 - 4205 个词 阅读量 0[译]在IEEE,IBM或VAX浮点数格式和字节表达式之间转换
原文地址:https://www.codeproject.com/Articles/12363/Transform-between-IEEE-IBM-or-VAX-floating-point-n
原文作者:John Jiyang Hou
译文由本站 robot-v1.0 翻译
前言
This program can transform between IEEE, IBM or VAX floating point number formats and their bytes expressions.
该程序可以在IEEE,IBM或VAX浮点数格式及其字节表达式之间转换.
介绍(Introduction)
该程序可以将浮点数转换为其字节表达式,也可以将字节表达式转换为浮点数.(This program can transform a floating point number to its bytes expression or transform a bytes expression to a floating point number.)
背景(Background)
您是否曾经尝试开发一种程序来读取DLIS(数字日志交换标准)格式的数据文件?我发现样本日志数据记录为VAX单浮点格式.因此,我不得不从二进制文件中读取4个字节的流,然后恢复实数.我成功恢复了所有通道的所有帧数据.我将我的结果与Schlumberger免费工具程序Toolbox的输出进行了比较.他们是相同的.我还使用免费的Java程序包Cynosurex进行了一些测试,结果相同.这使我想起了五年前我在浮点数和字节顺序分析方面所做的一些中途工作,激发了我重新进行下去的热情.(Have you ever tried to develop a program to read a DLIS (Digital Log Interchange Standard) format data file? I found that the sample log data was recorded as VAX single float format. So, I had to read a 4 bytes stream from the binary file, and then recover the real number. I succeeded to recover all the frame data for all the channels. I compared my result with the output of the Schlumberger free tool program, Toolbox. They were identical. I also did some test using a free Java package, Cynosurex, and it gave the same result. This reminded me some of some halfway jobs I did about floating point number and bytes order analysis five years ago, and inspired my enthusiasm to proceed again.)
浮点数的位表示(Bits expression of floating point number)
IEEE单精度浮点数:(IEEE single precision floating point:)
SEF : S EEEEEEEE FFFFFFF FFFFFFFF FFFFFFFF
bits : 1 2 9 10 32
bytes : byte1 byte2 byte3 byte4
IEEE双精度浮点数:(IEEE double precision floating point:)
SEF: S EEEEEEE EEEE FFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
bits: 1 2 12 13 64
bytes: byte1 byte2 byte3 byte4 byte5 byte6 byte7 byte8
frctn.: L1 L2
IBM单精度浮点数:(IBM single precision floating point:)
SEF : S EEEEEEE FFFFFFFF FFFFFFFF FFFFFFFF
bits : 1 2 8 9 32
bytes : byte1 byte2 byte3 byte4
IBM双精度浮点数:(IBM double precision floating point:)
SEF: S EEEEEEE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
bits: 1 2 8 9 64
bytes: byte1 byte2 byte3 byte4 byte5 byte6 byte7 byte8
frctn.: L1 L2
VAX单精度浮点数:(VAX single precision floating point:)
SEF : S EEEEEEEE FFFFFFF FFFFFFFF FFFFFFFF
bits : 1 2 9 10 32
bytes : byte2 byte1 byte4 byte3
浮点数的通用编码公式(General encoding formula of the floating point)
V = (-1)<SUP>S</SUP> * M * A<SUP>( E - B )</SUP>
M = C + F
V是值,S是符号,M是尾数,A是基数,E是指数,B是指数偏差,C是尾数常数,F是分数. A,B和C是与浮点体系结构可能不同的常数.这里是其中的一些:(V is the value, S is the sign, M is called mantissa, A is base, E is exponent, B is exponent bias, C is mantissa constant, and F is fraction. A, B and C are constants that could be different with the floating point architecture. Here are some of them:)
IEEE single float : A = 2 B = 127 C = 1
IEEE double float : A = 2 B = 1023 C = 1
IBM single float : A = 16 B = 64 C = 0
IBM double float : A = 16 B = 64 C = 0
VAX single float : A = 2 B = 128 C = 0.5
分数的最大值(Maximum value of the fraction)
如上所述,F是分数. IEEE和VAX分数F的最小值为0,IBM分数最小值为1/16. F为零表示所有小数位(上面的位表达式中的F)均为0.当所有小数位均为1时,将达到小数的最大值.要弄清楚这一点,我们必须使用一些高中数学,可以你还记得这个公式吗?(As mentioned above, F is the fraction. The minimum value of the IEEE and VAX fraction F is 0, and IBM fraction minimum value is 1/16. F is zero means all fraction bits (F of the bits expression above ) are 0. The maximum value of the fraction will be reached when all fraction bits are 1. To figure out it, we have to use a little high school mathematics, can you remember this formula?)
1/2 + 1/4 + 1/8 + ... + 1/2<SUP>n</SUP> = 1 - 1/2<SUP>n</SUP>
这里唯一容易忽略的细节是有关VAX单精度浮点的.除其有线字节顺序外,其小数位段从1/4开始,而不是从IEEE或IBM的1/2开始.这是另一个例子,说明复杂性总是来自人格.(The only easy ignored detail here is about the VAX single precision floating point. Except its wired bytes order, its fraction bits segment starts from 1/4, not from 1/2 as IEEE or IBM. This is another example for that complexity is always from personality.)
G is the maximum value of the fraction F
IEEE single float : G = 1 - 1/2<SUP>23</SUP>
IEEE double float : G = 1 - 1/2<SUP>52</SUP>
IBM single float : G = 1 - 1/2<SUP>24</SUP>
IBM double float : G = 1 - 1/2<SUP>56</SUP>
VAX single float : G = 1 - 1/2<SUP>24</SUP> - 1/2
尾数范围(Mantissa range)
根据上述C和G值很容易找出尾数范围.下面将解释IBM浮动尾数最小值.(It is easy to figure out the mantissa range based on the above values of C and G. The IBM float mantissa minimum value will be explained below.)
IEEE single float : 1 <= M <= 2 - 1/2<SUP>23</SUP>
IEEE double float : 1 <= M <= 2 - 1/2<SUP>52</SUP>
IBM single float : 1/16 <= M <= 1 - 1/2<SUP>24</SUP>
IBM double float : 1/16 <= M <= 1 - 1/2<SUP>56</SUP>
VAX single float : 1/2 <= M <= 1 - 1/2<SUP>24</SUP>
字节顺序(Bytes order)
我使用一个简单的联合数据结构和一个两个字节的无符号短整数258来找到用于存储该数字的字节顺序.对于Little Endian体系结构,例如:Intel,此函数将返回2;对于Big Endian体系结构,例如:SPARC,此函数将返回1.(I use a simple union data structure and a two bytes unsigned short integer 258 to find the kind of bytes order for your memory to store the number. For Little Endian architecture, such as: Intel, this function will return 2; for Big Endian architecture, such as: SPARC, this function will return 1.)
将字节转换为浮点(Transform bytes to floating point)
转换有两个步骤.第一步是将字节转换为SEF,这意味着符号,指数和分数.第二步是将SEF转换为浮点数.(There are two steps for the transformation. The first step is to transform bytes to SEF, which means Sign, Exponent, and Fraction. The second step is to transform SEF to a floating point number.)
1.字节到SEF:(1. Bytes to SEF:)
首先,调整输入字节的顺序以适合浮点的上述位表达式,然后可以根据上述位表达式通过一些位运算来获得SEF值.对于双精度浮点,我将分数分解为两部分:两个无符号长整数,分别为L1和L2.(Firstly, adjust the incoming bytes order to fit the above bits expression of floating point, then the SEF values can be gotten through some bits operation based on the above bits expression. For double precision floating point, I decompose the fraction into two parts: two unsigned long integers, which are L1 and L2.)
2. SEF到浮点:(2. SEF to floating point:)
根据上述一般编码公式以及三个常数A,B和C,很容易从SEF中恢复浮点数.(It is easy to recover the floating point number from SEF based on the above general encoding formula and the three constants A, B and C.)
将浮点转换为字节(Transform floating point to bytes)
与上述方法类似,转换有两个步骤.第一步是将浮点转换为SEF.第二步是将SEF转换为字节.(Similar with the above method, there are two steps for the transformation. The first step is to transform the floating point to SEF. The second step is to transform SEF to bytes.)
1. SEF的浮点数:(1. Floating point to SEF:)
这部分是所有程序中最重要的部分.我开发了两种方法来根据浮点数计算E和F.(This part is the most important in all programs. I developed two methods to calculate the E and F from the floating point number.)
第一种方法更自然.它的原理与将整数转换为其二进制表达式相同,后者通过连续除以2来获得每一位.在我们的情况下,我们可以连续除以或乘以直到商数落入上述尾数范围内.除法或乘法的选择取决于值E-B是正还是负,但是在知道E之前不可能知道值E-B的符号.实际上,我们可以通过将浮点数与尾数绑定值进行比较来确定它.循环时间用于确定E值,同时循环后原始浮点的剩余值用于确定F值.(The first method is more natural. Its principle is same as transforming an integer to its binary expression, which gets every bit through continually dividing the base 2. In our case, we can continually divide or multiply the base till the quotient settles within the mantissa range mentioned above. The choice of divide or multiply depends on whether the value E-B is positive or negative, but it is impossible to know the sign of the value E-B before E is known. Actually, we can determine it through comparing the floating point number with the mantissa bound value. The loop times is used to determine the E value, meantime, the surplus value of the original floating point after the loop is used to determine the F value.)
第二种方法有点复杂.它采用逆算法通过对数计算出E值,然后很容易通过上述编码公式得出F值.实际上,我们可以得出E和F的以下公式:(The second method is a little complex. It uses the reverse algorithm to figure out the E value by the logarithm, then it is easy to get the F value by the above encoding formula. Actually, we can conclude the following formula for E and F:)
V is the floating point number
D = log2 , base is e
IEEE single float : E = (int) ( logV / D + B )
IEEE double float : E = (int) ( logV / D + B )
IBM single float : E = (int) ( ( logV / D ) / 4 + 1 + B )
IBM double float : E = (int) ( ( logV / D ) / 4 + 1 + B )
VAX single float : E = (int) ( ( logV / D ) + 1 + B )
F = V / A<SUP>(E-B)</SUP> - C
我将简要说明这些公式.零值和符号S可以无害地忽略,因此浮点值假定为正:V> 0.(I will give a brief proof for these formulae. The zero value and the sign S can be harmlessly ignored, so the float value is assumed as positive: V > 0.)
-
IEEE浮点数:(IEEE float:)IEEE浮点数的尾数范围是:1 <=M <2.因此:0 <=logM/log2 <1.注意:E是一个非负整数,因此:(The mantissa range of the IEEE float is: 1 <= M < 2 . So: 0 <= logM / log2 < 1. Notice: E is a non-negative integer, so:)
-
IBM浮动:(IBM float:)RP66参考文档中提到了此处的关键点:(The key point here is mentioned in the RP66 reference document:)字节2的位1-4可能不全为零,但为零.换句话说,尾数的第一个十六进制数字必须为非零,但真零除外(Bits 1 - 4 of byte 2 may not all be zero except for true zero. In other words, the first hexadecimal digit of the mantissa must be non-zero, except for true zero).这意味着IBM浮动尾数最小值为1/16.因此:0 <logM/log16 + 1 <1.注意:E是一个非负整数.(. This means the IBM float mantissa minimum value is 1/16. So: 0 < logM / log16 + 1 < 1. Notice: E is a non-negative integer.)
-
VAX浮动:(VAX float:)VAX浮点尾数最小值为1/2,因此:0 <logM/log2 + 1 <1.注意:E是一个非负整数.(The VAX float mantissa minimum value is 1/2, so: 0 < logM / log2 + 1 < 1. Notice: E is a non-negative integer.)
2. SEF到字节(2. SEF to bytes)
这部分没有困难的事情.它只需要字节顺序调整和一些位操作即可.(There are no difficult things for this part. It just needs bytes order adjustment and some bits operation.)
这些程序还包括常规的Union方法,用于转换IEEE float及其字节表达式.(The programs also include a regular Union method to transform an IEEE float and its bytes expression.)
编译(Compile)
该程序在(This program was compiled in the) 最小GW(MinGW) Windows XP中的环境.您必须设置PATH环境变量或运行(environment in Windows-XP. You have to set the PATH environment variable or run)*setp.bat(setp.bat)*编译之前.(before compiling.)
set PATH = %PATH%; C:\MinGW\bin ;
然后跑(Then run)*棒棒(clib.bat)*创建库,或手动编译程序,如下所示:(to create the library, or manually compile the program as follows:)
del libNumber.lib
del *.o
g++ -c ByteOrder.c
g++ -c Float2SEF.c
g++ -c SEF2Byte.c
g++ -c Byte2SEF.c
g++ -c SEF2Float.c
g++ -c IeeeFloat.c
g++ -c IbmFloat.c
g++ -c VaxFloat.c
g++ -c TestlibNumber.c
ar m libNumber.lib
ar r libNumber.lib *.o
ar t libNumber.lib
del *.o
跑(Run)*cpsam.bat(cpsam.bat)*编译两个测试程序,如下所示:(to compile the two test programs as follows:)
cpsam test1
cpsam test2
毕竟,您可以运行(After all, you can run the)*test1.exe(test1.exe)*DOS窗口中的程序.您还可以将输出重定向到文本文件,如下所示:(program in a DOS window. You also can redirect the output to a text file as follows:)
test1 > test.txt
*test2.exe(test2.exe)*是另一个测试程序,用于测试此库的任何浮点数.(is another test program to test any float number for this library.)
参考(Reference)
我已将所有参考网页包装到我的源代码Zip包中.(I have wrapped all reference web pages into my source code Zip package.)
- http://http://www.psc.edu/general/software/packages/ieee/ieee.html(http://http://www.psc.edu/general/software/packages/ieee/ieee.html)
- IEEE浮点运算标准(The IEEE standard for floating point arithmetic) .(.)
- 浮点格式(Floating-Point Formats)
- IEEE标准754浮点数(IEEE Standard 754 Floating Point Numbers)
- 增值税(VAX)
- IBM浮点架构(IBM Floating Point Architecture)
- IEEE浮点标准(IEEE floating-point standard)
- 二进制数字系统(Binary numeral system)
- IEEE二进制浮点到字符串转换(IEEE binary float to string conversion)
- F_float_to_float(F_float_to_float)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C C++ Windows Visual-Studio Dev 新闻 翻译