如何在使用GCC或/和IAR进行编译时禁用双精度数学?

And*_*eyB 6 c c++ embedded gcc arm

我的嵌入式C代码正在运行Cortex M4F,具有单精度FPU.我担心编译器多久会把基于软件的双精度数学放在像这样的地方

**

float_var1 = 3.0 * int_var / float_var_2;
(3.0 instead of 3.0f)
Run Code Online (Sandbox Code Playgroud)

**

我担心我会错过这些双常数中的一些.如何找到所有出现的慢速双精度数学?禁用双精度或使用源GCC或IAR生成错误/警告可以执行此操作.

请指导我实现目标的正确方法.

Ali*_*Ali 9

如何找到所有出现的慢速双精度数学?禁用双精度或使用源GCC或IAR生成错误/警告可以执行此操作.

-Wdouble-promotion完全按照你的意愿行事,看看文档.顺便提一下,doc中的示例与您的示例非常相似.

这基本上是你的例子:

float f(int int_var, float float_var_2) {
  return 3.0 * int_var / float_var_2;
}
Run Code Online (Sandbox Code Playgroud)

这是当我将-Wdouble-promotion标志传递给gcc 时会发生什么:

GCC -c -Wdouble推广float.c
float.c:在函数"F":
float.c:2:24:警告:从"浮动"到"双重"的隐式转换以匹配的二进制表达的另一个操作数[-Wdouble -promotion]

如果您也传递了-Werror标记,则可以将该警告变为错误.


Ber*_*Ber 5

gcc 有一个优化选项 -fsingle-precision-constant,可以将普通浮点常量视为单精度:

-fsingle-precision-constant

将浮点常量视为单精度,而不是将它们隐式转换为双精度常量。


pab*_*977 3

作为快速解决方案,请尝试执行以下步骤:

  1. 通过后缀 f 附加到每个浮点常量:1.3f、3.1415f 等。
  2. 仅使用float变量。
    即使编译器进行了中间高精度计算,
    最终结果也会被截断为 的精度float
  3. 考虑到类型floatdoublelong double
    它们都试图遵循
    浮点标准 ISO/IEC/IEEE 60559执行的规则
    。请查看:C 的浮点标准
    该类型float旨在是single floating-point
    类型double的意图是什么double floating-point,以及它的意图是什么
    类型。 long doubleextended precistion floating-point
  4. (float)在计算的相关部分 进行转换。
  5. <math.h>使用带有后缀“f”的函数,
    该函数旨在接受和返回类型的值float

然而,所有早期的食谱都只是建议。
有时编译器会以 的精度进行中间计算long double
可以从标头中存在的宏中检索此信息<float.h>
例如:

   FLT_EVAL_METHOD  // gives information about the method used in intermediate evaluations  
   FLT_ROUNDS       // gives information about the rounding method  
Run Code Online (Sandbox Code Playgroud)

也许,要微调浮点计算的行为,您必须更深入地了解特定编译器的选项。