是否有一个printf说明符要求浮点数不是双倍?

当我使用带有float类型参数的snprintf “%f”说明符时,我得到MISRA类型错误。

根据我的研究,MISRA是正确的,因为“%f”预示着一种double类型。

是否有浮点说明符或修饰符将使用float类型参数而不是double

我正在研究嵌入式系统,并且不想将32位浮点数转换为64位double精度,只是为了取悦snprintf函数。 代码打印到调试/控制台端口,这是转换发生的唯一位置。

对于那些需要代码示例的人:

 // This section is for those C++ purists and it fulfills the C++ tag. #if __cplusplus #include  #else #include  #endif #define BUFFER_SIZE (128U) int main(void) { char buffer[BUFFER_SIZE]; float my_float = 1.234F; // The compiler will promote the single precision "my_float" // to double precision before passing to snprintf. (void)snprintf(buffer, BUFFER_SIZE, "%10.4f", my_float); puts(buffer); return 0; } 

我对SO和Web的所有研究都是关于打印一个浮点值,而不是关于哪些说明符需要一个float参数,这样就不会发生升级double

我正在为ARM7TDMI处理器使用IAR Embedded Workbench编译器。

不,因为printf及其朋友是可变函数,所以float参数会自动转换为double作为默认参数提升的一部分 (参见C99标准的6.5.2.2节)。

我不知道为什么这会引发MISRA警告,但我想不出任何可能导致危险的方法。

不,没有,因为标准促销在通过变量参数列表时将每个float参数转换为double

正确的MISRA-C:2004合规分析应该给出:

  • 违反1.1,代码不符合ISO 9899:1990(C ++代码,C99代码)。
  • 违反2.2,使用//评论。
  • 违反16.1,使用变量参数函数。
  • 违反20.9,使用stdio.h。

如果您遇到上述错误,您的静态分析仪可能会损坏。

我已手动分析,以及LDRA Testbed 7.6.0。

由于自动升级,因此无法在printf函数中指定float而不是double,但我认为您可以从以下位置更改代码:

 (void)snprintf(buffer, BUFFER_SIZE, "%10.4f", my_float); 

至:

 (void)snprintf(buffer, BUFFER_SIZE, "%10.4f", (double)my_float); 

并取得正确的结果