Floating point 反向工程未知浮点格式

Floating point 反向工程未知浮点格式,floating-point,reverse-engineering,ieee-754,ieee,Floating Point,Reverse Engineering,Ieee 754,Ieee,我正在尝试对一些旧文件格式(Cinema4D旧版本)进行反向工程,但找不到其规范 在这种文件格式中,我发现浮点值存储为四个字节,但它们似乎不是正常的IEEE格式,这不是endian问题。我最近花了很多时间使用hexfloat转换工具来解决这个问题 以下是一些示例值: 0 = 00 00 00 00 1 = 80 00 00 41 2 = 80 00 00 42 4 = 80 00 00 43 8 = 80 00 00 44 0.25 = 80 00 0

我正在尝试对一些旧文件格式(Cinema4D旧版本)进行反向工程,但找不到其规范

在这种文件格式中,我发现浮点值存储为四个字节,但它们似乎不是正常的IEEE格式,这不是endian问题。我最近花了很多时间使用hexfloat转换工具来解决这个问题

以下是一些示例值:

0     = 00 00 00 00
1     = 80 00 00 41
2     = 80 00 00 42
4     = 80 00 00 43
8     = 80 00 00 44

0.25  = 80 00 00 3F
16384 = 80 00 00 4F
我从上面两行中观察到,当从3F到4F时,这里似乎有东西缠绕着

1.5  = C0 00 00 41
2.5  = A0 00 00 42

-1   = 80 00 00 C1
-1.5 = C0 00 00 C1
-2   = 80 00 00 C2
-3   = C0 00 00 C2
因此,以下是一些观察结果:

  • 增加最后一个字节+1,值将加倍
  • 如果设置了最后一个字节的高位,则数字为负数
  • 第一个字节处理非整数值
  • 虽然有一些明显的模式,也有一些指数/尾数,但我还没有弄明白这一点。也许我甚至错过了一些明显的东西,这很正常?计算尾数/指数等的位数不是问题(在上面的示例中,中间两个字节为零),首先我需要计算得出浮点值的公式这里的线索是它首次出现在Commodore Amiga平台上,该平台使用FFP浮点格式,它似乎是为方便软件仿真而设计的。本手册第35章对此进行了解释:

    尾数被认为是一个二元不动点分数;除0外,它始终是标准化的(尾数被移位并调整指数,以便尾数在其最高位置有一个1位)。因此,它表示小于1但大于或等于1/2的值

    指数是正确定位尾数以反映数字真实算术值所需的二的幂。它以超额-64表示法持有,这意味着两个的补码值向上调整64,从而将$40(-64)到$3F(+63)更改为$00到$7F

    0的值定义为所有32位均为0

    尾数位存储在最高有效位的三个字节中,而最低有效位由其最高有效位中的符号位和最低有效位中的偏置指数组成。因此,除零外,32位数字
    x
    的数值为(-1)x*(x/224)*2(x-64)

    基于此,下面的ISO-C99代码提供了一个函数
    decode\u ffp()
    ,该函数返回以无符号32位整数形式提供的ffp浮点数的数值。请注意,伪零和非规范化编码的行为没有定义,因为官方文档没有说明应该如何处理它们

    #包括
    #包括
    #包括
    #包括
    浮点解码ffp(uint32\U t a)
    {
    const uint32_t FFP_EXPO_BIAS=64;
    const uint32_t FFP_MANT_BITS=24;
    const uint32_t FFP_EXPO_BITS=7;
    const uint32\u t FFP\u EXPO\u掩码=(1>(FFP\u EXPO\u位+1);
    uint32符号=(a>>FFP\u EXPO\u BITS)&1;
    int32世博会=(a&FFP世博会面具)-FFP世博会偏见;
    浮动增值税;
    如果(a==0){
    val=0.0f;
    }否则{
    
    val=exp2f(expo)*mant/(1可能是前三个字节是完整的有效位(包括前导的1)。@Sneftel:在我看来也是这样。将前三个字节视为在
    [0.5,1.0]中给出有效位
    ,最后一个字节的顶部位是符号,剩余的7位给出了一个超64指数。但这与我所知道的任何常见浮点格式都不匹配(不是IEEE 754,不是VAX,不是IBM,不是Cray…)。非常感谢这两位,这正是它的本来面目(这可能是在fpu普及之前,如果包含前导1,在软件中实现可能会更快)如果它们在有效位中显示前导1,请注意输入中可能存在非标准化数字。也就是说,也可能将2表示为40 00 00 43。