【问题标题】:Convert TI TMS320C30 32 bits float to IEEE float in python [closed]在python中将TI TMS320C30 32位浮点转换为IEEE浮点[关闭]
【发布时间】:2020-11-04 20:16:41
【问题描述】:

我需要将 TI TMS320C30 32 位浮点数转换为 IEEE 浮点数。我找到了逆问题的解决方案,但到目前为止,我无法通过将 TMS320C30 32 位浮点数转换为 IEEE 754 来实现任何目标。有什么想法可以做到这一点吗?

Convert IEEE float to TI TMS320C30 32bits float in python

【问题讨论】:

  • 链接问题中链接到的 TI 文档似乎包含有关如何进行转换的所有详细信息。这很粗糙,可能需要一天的工作才能正确完成。一旦所有位都在正确的位置,struct.pack and struct.unpack 会给你最终的浮动。

标签: python floating-point ieee-754 texas-instruments


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 2014-10-18
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多