VAX 机器上的浮点数
Floating Point numbers on VAX machine
我有 VAX 机器上旧应用程序 运行 的 RTL/2 程序语言源代码。
不幸的是,我没有 possibility\ability 来重新编译应用程序。
我必须更改一些系数(实数,“有线代码”)
所以我有了一个想法:我可以直接更改可执行文件中的这些数字(一些 .cm8 文件,这些是大文件,所有行都以“:”开头,然后是一种地址和十六进制数据)
不幸的是,如果我取其中一个系数 (es 3.8262619e-09) 并以二进制表示,我会得到:
es 3.8262619e-09 In binary is : 00110001100000110111100000101000 hex is: 0x31837828 hex in reverse endianess: 0x28788331
但是如果我在可执行文件中搜索那些十六进制...我找不到匹配项。如果我能在可执行文件中找到这些数字,我想直接更改它们。
我认为,问题是 VAX 机器不使用 IEEE 754 标准表示浮点数。
我找到了这个 link
https://nssdc.gsfc.nasa.gov/nssdc/formats/VAXFloatingPoint.htm
这解释了 vax 机器上的浮点表示,
但我不明白如何以 VAX 浮点格式表示我的实数(即我直接在源代码中找到的 0.38262619E-08)。
有什么帮助吗?
此答案假定用于 floating-point 数据的格式是 32 位 VAX F_floating
格式。这类似于 IEEE-754 binary32
。规范化二进制 floating-point 格式,允许将有效数(尾数)的最高有效位假定为 1 并且不存储。两者都使用 8 位偏置指数。
binary32
格式的有效范围为 [1, 2),而 F_floating
的有效范围为 [0.5, 1)。 binary32
格式使用的指数偏差为 127,而 F_floating
格式的指数偏差为 128。结合起来,这意味着两种格式中相同的编码在数字上偏移了四倍。 F_floating
格式不支持有符号零、次正规、无穷大和 NaN。
由于与 16 位 PDP-11 兼容,F_floating
使用 non-intuitive 字节存储顺序。当按地址升序检查内存映像时,F_floating
操作数的四个字节以 2、3、0、1 的顺序出现。
对于以下 ISO-C99 程序,我假设代码在使用 IEEE-754 floating-point 算法的系统上执行。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <string.h>
#include <math.h>
uint32_t float_as_uint32 (float a)
{
uint32_t r;
memcpy (&r, &a, sizeof r);
return r;
}
/* Convert a IEEE-754 'binary32' operand into VAX F-float format, represented
by a sequence of four bytes in ascending address order. Underflow is handled
with a flush-to-zero response. Overflow is not handled!
*/
void float_to_vaxf (float a, uint8_t *b)
{
const float TWO_TO_M128 = 2.93873588e-39f; // 2**(-128)
const float SCAL = 4; // factor between IEEE-754 'binary32' and VAX F-float
const float ZERO = 0.0f; // canonical zero
uint32_t t;
// adjust for exponent bias and significant range
a = a * SCAL;
// no support for subnormals in VAX F_floating, flush to zero
if (fabsf (a) < TWO_TO_M128) a = ZERO;
t = float_as_uint32 (a);
// adjust to VAX F_floating byte ordering
b[0] = (uint8_t)(t >> 2 * CHAR_BIT);
b[1] = (uint8_t)(t >> 3 * CHAR_BIT);
b[2] = (uint8_t)(t >> 0 * CHAR_BIT);
b[3] = (uint8_t)(t >> 1 * CHAR_BIT);
}
int main (void)
{
float a = 3.8262619e-9f;
uint8_t vf[4];
float_to_vaxf (a, vf);
printf ("% 15.8e as VAX F-float bytes: 0x%02x,0x%02x,0x%02x,0x%02x\n",
a, vf[0], vf[1], vf[2], vf[3]);
return EXIT_SUCCESS;
}
我有 VAX 机器上旧应用程序 运行 的 RTL/2 程序语言源代码。 不幸的是,我没有 possibility\ability 来重新编译应用程序。 我必须更改一些系数(实数,“有线代码”)
所以我有了一个想法:我可以直接更改可执行文件中的这些数字(一些 .cm8 文件,这些是大文件,所有行都以“:”开头,然后是一种地址和十六进制数据)
不幸的是,如果我取其中一个系数 (es 3.8262619e-09) 并以二进制表示,我会得到:
es 3.8262619e-09 In binary is : 00110001100000110111100000101000 hex is: 0x31837828 hex in reverse endianess: 0x28788331
但是如果我在可执行文件中搜索那些十六进制...我找不到匹配项。如果我能在可执行文件中找到这些数字,我想直接更改它们。 我认为,问题是 VAX 机器不使用 IEEE 754 标准表示浮点数。 我找到了这个 link https://nssdc.gsfc.nasa.gov/nssdc/formats/VAXFloatingPoint.htm 这解释了 vax 机器上的浮点表示, 但我不明白如何以 VAX 浮点格式表示我的实数(即我直接在源代码中找到的 0.38262619E-08)。
有什么帮助吗?
此答案假定用于 floating-point 数据的格式是 32 位 VAX F_floating
格式。这类似于 IEEE-754 binary32
。规范化二进制 floating-point 格式,允许将有效数(尾数)的最高有效位假定为 1 并且不存储。两者都使用 8 位偏置指数。
binary32
格式的有效范围为 [1, 2),而 F_floating
的有效范围为 [0.5, 1)。 binary32
格式使用的指数偏差为 127,而 F_floating
格式的指数偏差为 128。结合起来,这意味着两种格式中相同的编码在数字上偏移了四倍。 F_floating
格式不支持有符号零、次正规、无穷大和 NaN。
由于与 16 位 PDP-11 兼容,F_floating
使用 non-intuitive 字节存储顺序。当按地址升序检查内存映像时,F_floating
操作数的四个字节以 2、3、0、1 的顺序出现。
对于以下 ISO-C99 程序,我假设代码在使用 IEEE-754 floating-point 算法的系统上执行。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <string.h>
#include <math.h>
uint32_t float_as_uint32 (float a)
{
uint32_t r;
memcpy (&r, &a, sizeof r);
return r;
}
/* Convert a IEEE-754 'binary32' operand into VAX F-float format, represented
by a sequence of four bytes in ascending address order. Underflow is handled
with a flush-to-zero response. Overflow is not handled!
*/
void float_to_vaxf (float a, uint8_t *b)
{
const float TWO_TO_M128 = 2.93873588e-39f; // 2**(-128)
const float SCAL = 4; // factor between IEEE-754 'binary32' and VAX F-float
const float ZERO = 0.0f; // canonical zero
uint32_t t;
// adjust for exponent bias and significant range
a = a * SCAL;
// no support for subnormals in VAX F_floating, flush to zero
if (fabsf (a) < TWO_TO_M128) a = ZERO;
t = float_as_uint32 (a);
// adjust to VAX F_floating byte ordering
b[0] = (uint8_t)(t >> 2 * CHAR_BIT);
b[1] = (uint8_t)(t >> 3 * CHAR_BIT);
b[2] = (uint8_t)(t >> 0 * CHAR_BIT);
b[3] = (uint8_t)(t >> 1 * CHAR_BIT);
}
int main (void)
{
float a = 3.8262619e-9f;
uint8_t vf[4];
float_to_vaxf (a, vf);
printf ("% 15.8e as VAX F-float bytes: 0x%02x,0x%02x,0x%02x,0x%02x\n",
a, vf[0], vf[1], vf[2], vf[3]);
return EXIT_SUCCESS;
}