问题描述
我需要将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