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.

[参考译文] TMS320F28377S:如何确保对于浮点值、存储器中的十六进制内容是相同的

Guru**** 2445440 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1035490/tms320f28377s-how-to-make-sure-the-hex-content-in-memory-is-the-same-for-floating-point-value

器件型号:TMS320F28377S

您好、TI

在我的代码中、  

static float foo=1.08;   // hex value in memory for foo is 3F8A3D71, the actual float value = 1.08000004

foo = 1080.0 / 1000.0;   // hex value in memory for foo becomes 3F8A3D70, the actual float value = 1.07999992

由于我们根据十六进制内容计算校验和、因此即使出于我们的目的的实际 foo 值没有改变、校验和也会返回不同的值。 您能否告知我们是否可以保证两个步骤的十六进制值保持不变? 此外、如果您需要更多信息、请告诉我。

非常感谢、

CLIO

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

    您好!

    我无法重现此问题、如下所示:

    您使用的是什么编译器和目标文件格式? 您可以添加'f'后缀并尝试吗?  

    -Shantanu

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

    您好、shanty、

    我的 INIT 帖子中有错误、抱歉。

    请尝试以下操作:

    static signed long int c = 9200;
    static float a;
    static float b;
    a = (float)c / (10000.0f);
    b = (float)9200 / 10000.0f;

    非常感谢。

    CLIO

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

    你(们)好

    到 b、您分配了编译时间常量。 A 在运行时计算。 a 应等于 b、除非可能清除了 FPU STF.RND32或禁用了 FP 舍入的其他原因。

    但我不理解您如何解决该校验和问题。 如果您获取二进制数据(包括 FP 变量和常量)、那么该二进制数据的校验和(可能会发送到 PC)当然校验和应该匹配。 但是、如果您在获取校验和和验证之间对数据进行一些计算、则可能会有与预期不同的计算结果。

    Edward

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

    尊敬的 Edward:

    我在我们的项目中检查了 RND32、它的值实际上是0。

    在我们的项目中、我们有浮点计算。 我们如何将该 RND32设置为1? 您能给我们一些关于配置 FPU 寄存器的提示吗?  

    我尝试将 RND32设置为1、但仍然无法获得相同的十六进制值。 :(

    关于校验和 conundrum、我们首先根据常量计算校验和、然后当用户更改该值时(即计算发生时)、再次计算校验和。 这时、我们注意到校验和发生了变化、而实际值没有发生变化。

    再次感谢您的见解

    CLIO

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

    您好、Clio、

    是的、应始终设置 RND32、这会导致更准确的+-*/结果、并影响所有 FP 数学库的精度。  

    默认情况下、在 C2000编译器库中设置 RND32。 请参阅库源引导28.asm 中的。 它具有这些线路

    如果.TMS320C2800_FPU32
    SETFLG RNDF32=1;启用 FPU32模式中的舍入。
    .endif

    您是否在使用某些 RTOS? 我遇到了 FreeRTOS 问题。 我使用的 FreeRTOS 源在清除 RND32的情况下创建任务...

    关于 RND32和除法、很遗憾、我现在没有 JTAG 软件狗来测试它。 也许稍后、不确定时间。

    据我所知、您使用校验和来验证用户是否更改了某些设置。 然后、在生成初始数据和检查用户输入时、应通过相同的计算路径。 无论 FP 支持有多差、校验和都将匹配、无论是否设置了 RND32。 也许在获取初始校验和以及在用户输入之后使用的常见计算例程是最好的。

    Edward

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

    尊敬的 Edward:

    是的、我们使用的是 boot28.asm、您突出显示的部分就位了。

    从我们的实验中可以看出、即使 RND32 设置为1、编译时存储在闪存中的字面浮点值的十六进制值(例如0.92f)仍然不同于运行时执行的浮点除法(例如9200/10000.0f)。  

    因此、根据我们的实验和上面的注释、我们了解 到无法配置编译器/DSP 来为上述两个运算生成相同的十六进制值。 如果您可以确认这一说法、我们将以其他方式关注我们的解决方案。 但我们仍然感谢您的见解。  

    BTW、我们的初始数据是存储在闪存中的硬编码浮点值。 因此、让它通过"相同的计算路径"有点困难。

    谢谢、

    CLIO

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

    您好、Clio、

    很奇怪、您使用的是哪个变体 a)具有编译器严格设置的软件 FP、b)快速数学库、c) TMU 和宽松设置而不是严格设置?

    我将测试我使用的每个新 MCU 系列的 FP 正确性。 (至少 W.Kahan 的 paranoia 是我必须运行的新 MCU 系列/编译器工具链)。 28377S+-*没有问题,它们是完美的。 但除法 会产生如您所见的效果。

    快速数学取除数的倒数、然后乘以被除数、a *(1/b)。  根据 IEEE754、舍入为最近模式(RND32)的一个 FP 操作应提供精确到<=0.5 ULP 的结果(单位至少在一个位置、或如您所见的那样的一个位差)。 但是、由于我们一行中有两个运算、而不是一个运算、因此最终结果不精确到+-0.5ULP。 这就是运行时除法和 PC 上除法(编译器)之间的区别。

    TMU DIVF32指令似乎具有与快速数学库相同的问题。 也许内部 TMU 会执行相同的两个运算、即倒数+乘法。

    您有两个选项:a)运行时以相同的方式计算、b)考虑可能的1ulp 差异。 a)校验和不应该有问题、b)只能帮助比较数字、不适合校验和。

    Edward

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

    尊敬的 Edward:

    我们使用的设置为:--fp-mode=relaxed,--fp-reassoc=off,f32,tmu0,vcu2... 话虽如此、我还尝试了-fp-mode=strict 和-fp-reassoc=on、 观察到的结果相同、即两个浮点运算中的十六进制值不同。

    目前、我们接受这是处理器/编译器/库中的一个限制、并专注于使用您建议的选项制定替代方案。 如果您的朋友曾针对此问题制定了更新、请告知我们。  

    非常感谢您的支持、  

    CLIO

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

    您好、Clio、

    tpu0+esRelaes 最快的选择是硬件限制(DIVF32指令)。

    最慢的选项,--fp-mode=strict,软件 fp 除法是可修复的。 实际上、我有一个针对这个库例程的修复程序。 但是、是否会真正使用这种缓慢的选项? 在软件中分频速度较慢、而您可以使用 FPU 是没有意义的。 除非您使用单个裂变浮点进行非常精确的操作、否则双精度显然会在精度方面胜出。   

    哦、另一个选项适合您、因为它是用户输入、不应太快、为什么不使用双精度(C2800编译器中的 long long double)。 类似的东西

    b =(超长双精度) 9200/10000.0LL;

    Edward

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

    尊敬的 Edward:

    我尝试使用双精度型、结果没有变化。

    在我们的项目中、FP 计算速度很重要。 您说设置--fp-mode=relaxed 会导致更快的计算时间吗? 我可能已经偏离了原来的问题、但其他哪些编译器开关会影响 FP 计算速度?

    CLIO

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

    IIRC --fp-mode=relaxed 允许编译器使用 TMU DIVF32指令。 严格来说、您必须使用软件 FP div 仿真。  

    如果您对双精度 div 有相同的问题、那么看起来 long double 到浮点转换不会舍入。 让我下周检查一下这个问题。

    Edward

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

    您好、Clio、

    它确实 起作用

    int c = 9200;

    a =(长双精度) c / 10000.0L;  

    b =(浮点) 9200/10000.0f;。  

    a 和 b 是相同的位

    Edward

    编辑:请不要让编译器让您像我一样充满、应该使用 A、否则编译器可能会优化存储到操作。  

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

    尊敬的 Edward:

    我的编译器是 v18.1.0.LTS

    我已经尝试过您的建议、它的工作原理如下所示。 但我不明白为什么第647行不会编译  

    我很高兴我们有权变措施。

    感谢您的建议、

    CLIO

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

    v18.1.0.8LTS 在该行(double) c 编译中可以正常运行、但请记住、double 与32位 TI C2000编译器中的 float 相同。 long double 是64位。

    Edward

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

    尊敬的 Edward:

    您说下面的647行不会编译  v18.1.0.LTS、而是使用编译器版本 v18.1.0.LTS 进行编译吗?

    我尝试使用 double 和 long double、 但我尝试的任何内容都不 会编译。

    CLIO

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

    您好、Clio、

    我没有18.1.1。 18.1.8之前版本的647行编译良好,并具有适当的64位除法。 新版本看起来不会错,但我可能不会多计算()。 您收到了什么错误消息? 如果没有任何帮助、 尝试升级编译器。

    Edward

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

    尊敬的 Edward:

    对于647行,我尝试了各种组合,但没有可用...这是错误消息

    当然、我们将尝试升级编译器。

    谢谢、

    CLIO

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

    您好!

    实际上、18.1.8编译该值就可以了

      a =(float)((long double) c)/(10000.00L);

    下次能否发布文本代码而不是图片? 它会保存我的键入内容。

    Edward