This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/TMS320F28335:运算浮点

Guru**** 2606725 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/681834/compiler-tms320f28335-operations-floating-point

器件型号:TMS320F28335

工具/软件:TI C/C++编译器

您好!

我的操作结果有问题。 运算涉及乘法和除法。 如果您在"Expressions"窗口中观看、结果似乎是正确的、但如果您转换值并检查内存浏览器、结果则不正确。

我简化了操作、只是为了显示问题。

int c = 66、d = 800;

浮点 A;

a=(c/1.1)*(d/d);

表达式窗口中出现的结果为60、但在内存浏览器中为0x426FFFFF、即59.999999。

我想这是因为浮点、但如果我直接使用数字、结果是正确的。

我应该如何进行操作?

谢谢、

帕洛马

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    帕洛马、

    你是对的。 该误差是32位浮点中有限分辨率的伪影。 之所以会出现这种情况、是因为执行除法时66和1.1中的不同指数(FPU32使用 IEEE745浮点格式、其中30-32位定义指数)。

    如果您将数字硬编码到代码中、编译器会在编译时为您执行计算并将结果直接加载到存储器中、从而为您提供帮助。 您可以在下面生成的装配体中看到这一点:

    A=(A/66/1.1)*(800/800);
    00a602:E8021380 MOVIZ R0、#0x4270
    00a604:E203000A MOV32 @0xA、R0H

    此外、如果我声明:

    浮点 x1 = 66/1.1;
    浮点 x2 = 800/800;

    我得到:

    a = x1*x2;
    00a606:E2A0006 MOV32 R0H、@0x6、UNCF
    00a608:E2AF0108 MOV32 R1H、@0x8、UNCF
    00a60a:E7000008 MPYF32 R0H、R1H、R0H
    00a60c:7700 NOP
    00a60d:E203000A MOV32 @0xA、R0H

    在这两种情况下、将加载编译器计算结果的寄存器、而 FPU 不执行任何操作。 您正在正确执行计算。 对于32位浮点、该误差是不可避免的。

    此致、

    Richard
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否认为在‘A’中添加+0.5是一个好主意来将其四舍五入? 我想概括一下结果、而不仅仅是为了获得60。

    非常感谢。

    帕洛马
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    帕洛马、

    不、我认为这是不可靠的。 您可以使用 roundf(),如下所示:
    a = roundf(浮点数)(c/1.1)*(d));

    roundf()大约需要130个周期,因此如果您经常使用它,则必须记住这一点。

    此致、

    Richard