将python中的TI TMS320C30 32位float转换为IEEE float

问题描述

我需要将TI TMS320C30 32位浮点数转换为IEEE浮点数。我找到了反问题的解决方案,但到目前为止,将32位浮点型TMS320C30转换为IEEE 754仍无法实现任何目的。有什么想法怎么做?

Convert IEEE float to TI TMS320C30 32bits float in python

解决方法

上一个问题中的document链接提供了TMS320C30浮点格式的所有必要详细信息:Randy Restle和Adam Cron,“ TMS320C30-IEEE浮点格式转换器”,应用报告SPRA400,德州仪器(TI),1997年

TMS格式不支持无限性,NaN,带符号的零或非正规数。 8位指数存储为2的补码整数,不像IEEE-754 binary32格式那样有偏。有效数字(尾数)不包含与IEEE-754匹配的隐式整数位。但是,对于负数操作数,有效数基本上存储为负数。

要从TMS格式转换为IEEE-754 binary32格式,我们基本上需要对指数施加偏差,对负操作数的有效位取反(必要时对指数进行校正),并且重新排列符号,指数和有效字段的顺序。

一个小的复杂之处在于TMS格式可以将幅度 -126 的数字表示为归一化的浮点数,而IEEE-754 binary32只能将它们存储为子范数。在这种情况下,我们需要使有效位数的隐藏整数位可见并反规范化。由于这会丢弃最低有效位,因此我们需要舍入结果。

我不懂Python,但是相信下面的ISO-C程序将很容易被该语言的熟练人员翻译成Python。格式转换是对各个浮点格式的位表示进行的,因此,它们被表示为转换函数tms_to_ieee()的无符号32位整数。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>

uint32_t tms_to_ieee (uint32_t a)
{
    uint32_t frac = a & 0x7fffff;
    uint32_t sign = (a >> 23) & 1;
    uint32_t expo = (a >> 24) & 0xff;
    uint32_t rslt;

    if (expo == 0x80) { // zero or implied zero
        expo = 0;
        frac = 0;
        sign = 0;
    } else {
        /* add IEEE exponent bias of 127 */
        expo = (expo + 0x7f) & 0xff;
        if (sign) {
            /* complement fraction */
            frac = 0x00800000 - frac;
            /* propagate fraction overflow to exponent */
            expo = expo + (frac >> 23);
            /* clear potential overflow */
            frac = frac & 0x7fffff;
        }
        if (expo == 0) {
            /* make implicit integer bit explicit */
            frac = frac + 0x00800000;
            /* denormalize,round to nearest-or-even */
            frac = (frac >> 1) + ((frac & 3) == 3);
        }
    }
    rslt = (sign << 31) | (expo << 23) | frac;
    return rslt;
}

float uint32t_as_float (uint32_t a)
{
    float r;
    memcpy (&r,&a,sizeof r);
    return r;
}

#define N  (60)  // number of test vectors

int main (void)
{
    uint32_t in[N] = {
        0x7f7fffff,0x7f7ffffe,0x7f7ffffd,0x7f7ffffc,0x7f000000,0x7e7fffff,0x7e7ffffe,0x7e7ffffd,0x00000000,0xff7fffff,0xff7ffffe,0xff7ffffd,0xff000000,0xfe7fffff,0xfe7ffffe,0xfe7ffffd,0x82000000,0x817fffff,0x817ffffe,0x817ffffd,0x817ffffc,0x81000002,0x81000001,0x81000000,0x807fffff,0x807ffffe,0x807ffffd,0x80000001,0x80000000,0x80ffffff,0x80fffffe,0x80fffffd,0x80800003,0x80800002,0x80800001,0x80800000,0x81ffffff,0x81fffffe,0x81fffffd,0x81800002,0x81800001,0x81800000,0x82ffffff,0x82fffffe,0x82fffffd,0xff800001,0xff800000,0x00ffffff,0x00fffffe,0x00fffffd,0x00800001,0x00800000,0x01ffffff,0x01fffffe,0x01fffffd,0x7fffffff,0x7ffffffe,0x7ffffffd,0x7f800001,0x7f800000,};
    float out[N] = {
        (2-exp2(-23)) * exp2(127),(2-exp2(-22)) * exp2(127),(2-exp2(-21)+exp2(-23)) * exp2(127),(2-exp2(-21)) * exp2(127),exp2(127),(2-exp2(-23)) * exp2(126),(2-exp2(-22)) * exp2(126),(2-exp2(-21)+exp2(-23)) * exp2(126),1,1-exp2(-24),1-exp2(-23),1-exp2(-22)+exp2(-24),exp2(-1),(2-exp2(-23)) * exp2(-2),(2-exp2(-22)) * exp2(-2),(2-exp2(-21)+exp2(-23)) * exp2(-2),exp2(-126),(2-exp2(-23)) * exp2(-127),(2-exp2(-22)) * exp2(-127),(2-exp2(-21)+exp2(-23)) * exp2(-127),(2-exp2(-21)) * exp2(-127),(1+exp2(-22)) * exp2 (-127),(1+exp2(-23)) * exp2 (-127),exp2(-127),(-1-exp2(-23)) * exp2(-127),(-1-exp2(-22)) * exp2(-127),(-1-exp2(-21)+exp2(-23)) * exp2(-127),(-2+exp2(-22)) * exp2(-127),(-2+exp2(-23)) * exp2(-127),-exp2(-126),(-1-exp2(-23)) * exp2 (-126),(-1-exp2(-22)) * exp2 (-126),(-1-exp2(-21)+exp2(-23)) * exp2 (-126),-1+exp2(-24),-exp2(0),(-1-exp2(-23)) * exp2(0),(-1-exp2(-22)) * exp2(0),(-1-exp2(-21)+exp2(-23)) * exp2(0),-2+exp2(-23),-2,-2-exp2(-22),-2-exp2(-21),-2-exp2(-20)+exp2(-22),(-1-exp2(-23)) * exp2(127),(-1-exp2(-22)) * exp2(127),(-1-exp2(-21)+exp2(-23)) * exp2(127),(-2+exp2(-23)) * exp2(127),-exp2(128)
    };

    for (int i = 0; i < N; i++) {
        uint32_t argi = in [i];;
        uint32_t resi = tms_to_ieee (argi);
        float resf = uint32t_as_float (resi);
        float reff = out[i];
        printf ("tms=%08x  ieee=%08x % 15.8e  ref=% 15.8e  %s\n",argi,resi,resf,reff,(resf == reff) ? "PASS" : "FAIL");
    }
    return EXIT_SUCCESS;

}

包含的小测试程序的输出应类似于以下内容:

tms=7f7fffff  ieee=7f7fffff  3.40282347e+038  ref= 3.40282347e+038  PASS
tms=7f7ffffe  ieee=7f7ffffe  3.40282326e+038  ref= 3.40282326e+038  PASS
tms=7f7ffffd  ieee=7f7ffffd  3.40282306e+038  ref= 3.40282306e+038  PASS
tms=7f7ffffc  ieee=7f7ffffc  3.40282286e+038  ref= 3.40282286e+038  PASS
tms=7f000000  ieee=7f000000  1.70141183e+038  ref= 1.70141183e+038  PASS
tms=7e7fffff  ieee=7effffff  1.70141173e+038  ref= 1.70141173e+038  PASS
tms=7e7ffffe  ieee=7efffffe  1.70141163e+038  ref= 1.70141163e+038  PASS
tms=7e7ffffd  ieee=7efffffd  1.70141153e+038  ref= 1.70141153e+038  PASS
tms=00000000  ieee=3f800000  1.00000000e+000  ref= 1.00000000e+000  PASS
tms=ff7fffff  ieee=3f7fffff  9.99999940e-001  ref= 9.99999940e-001  PASS
tms=ff7ffffe  ieee=3f7ffffe  9.99999881e-001  ref= 9.99999881e-001  PASS
tms=ff7ffffd  ieee=3f7ffffd  9.99999821e-001  ref= 9.99999821e-001  PASS
tms=ff000000  ieee=3f000000  5.00000000e-001  ref= 5.00000000e-001  PASS
tms=fe7fffff  ieee=3effffff  4.99999970e-001  ref= 4.99999970e-001  PASS
tms=fe7ffffe  ieee=3efffffe  4.99999940e-001  ref= 4.99999940e-001  PASS
tms=fe7ffffd  ieee=3efffffd  4.99999911e-001  ref= 4.99999911e-001  PASS
tms=82000000  ieee=00800000  1.17549435e-038  ref= 1.17549435e-038  PASS
tms=817fffff  ieee=00800000  1.17549435e-038  ref= 1.17549435e-038  PASS
tms=817ffffe  ieee=007fffff  1.17549421e-038  ref= 1.17549421e-038  PASS
tms=817ffffd  ieee=007ffffe  1.17549407e-038  ref= 1.17549407e-038  PASS
tms=817ffffc  ieee=007ffffe  1.17549407e-038  ref= 1.17549407e-038  PASS
tms=81000002  ieee=00400001  5.87747316e-039  ref= 5.87747316e-039  PASS
tms=81000001  ieee=00400000  5.87747175e-039  ref= 5.87747175e-039  PASS
tms=81000000  ieee=00400000  5.87747175e-039  ref= 5.87747175e-039  PASS
tms=807fffff  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=807ffffe  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=807ffffd  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80000001  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80000000  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80ffffff  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80fffffe  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80fffffd  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80800003  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80800002  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80800001  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=80800000  ieee=00000000  0.00000000e+000  ref= 0.00000000e+000  PASS
tms=81ffffff  ieee=80400000 -5.87747175e-039  ref=-5.87747175e-039  PASS
tms=81fffffe  ieee=80400001 -5.87747316e-039  ref=-5.87747316e-039  PASS
tms=81fffffd  ieee=80400002 -5.87747456e-039  ref=-5.87747456e-039  PASS
tms=81800002  ieee=807fffff -1.17549421e-038  ref=-1.17549421e-038  PASS
tms=81800001  ieee=80800000 -1.17549435e-038  ref=-1.17549435e-038  PASS
tms=81800000  ieee=80800000 -1.17549435e-038  ref=-1.17549435e-038  PASS
tms=82ffffff  ieee=80800001 -1.17549449e-038  ref=-1.17549449e-038  PASS
tms=82fffffe  ieee=80800002 -1.17549463e-038  ref=-1.17549463e-038  PASS
tms=82fffffd  ieee=80800003 -1.17549477e-038  ref=-1.17549477e-038  PASS
tms=ff800001  ieee=bf7fffff -9.99999940e-001  ref=-9.99999940e-001  PASS
tms=ff800000  ieee=bf800000 -1.00000000e+000  ref=-1.00000000e+000  PASS
tms=00ffffff  ieee=bf800001 -1.00000012e+000  ref=-1.00000012e+000  PASS
tms=00fffffe  ieee=bf800002 -1.00000024e+000  ref=-1.00000024e+000  PASS
tms=00fffffd  ieee=bf800003 -1.00000036e+000  ref=-1.00000036e+000  PASS
tms=00800001  ieee=bfffffff -1.99999988e+000  ref=-1.99999988e+000  PASS
tms=00800000  ieee=c0000000 -2.00000000e+000  ref=-2.00000000e+000  PASS
tms=01ffffff  ieee=c0000001 -2.00000024e+000  ref=-2.00000024e+000  PASS
tms=01fffffe  ieee=c0000002 -2.00000048e+000  ref=-2.00000048e+000  PASS
tms=01fffffd  ieee=c0000003 -2.00000072e+000  ref=-2.00000072e+000  PASS
tms=7fffffff  ieee=ff000001 -1.70141204e+038  ref=-1.70141204e+038  PASS
tms=7ffffffe  ieee=ff000002 -1.70141224e+038  ref=-1.70141224e+038  PASS
tms=7ffffffd  ieee=ff000003 -1.70141244e+038  ref=-1.70141244e+038  PASS
tms=7f800001  ieee=ff7fffff -3.40282347e+038  ref=-3.40282347e+038  PASS
tms=7f800000  ieee=ff800000 -1.#INF0000e+000  ref=-1.#INF0000e+000  PASS