为什么 printf() 将浮点数提升为双精度数?

来自之前的问题:p><块引用>

如果您尝试将 float 传递给 printf,它将被提升为 doubleprintf 收到之前

printf() 是可变参数函数吗?那么可变参数函数是否在传递 float 参数之前将其提升为 double?

解决方案

是的,可变参数函数的浮点参数被提升为双精度.

C99 标准草案部分 6.5.2.2 函数调用说:

<块引用>

[...] 和论据具有 float 类型的提升为 double.这些被称为默认参数促销活动.[...]

来自C++ 标准草案 section 5.2.2 函数调用:

<块引用>

[...] 一种受浮点数约束的浮点类型提升(4.6),参数的值转换为在调用之前提升类型.[...]

4.6部分:

<块引用>

float 类型的纯右值可以转换为 double 类型的纯右值.值不变

cppreference 涵盖了 默认转换 用于 C++ 中的可变参数函数:

<块引用>
  • std::nullptr_t 转换为 void*
  • float 参数被转换为 double ,就像在浮点提升中一样
  • bool、char、short 和无作用域枚举转换为 int 或更宽的整数类型,如整数提升中一样

我们可以在 C 和大概在 C++ 中看到这种转换是为了与 K&RC 兼容而保留的,来自 国际标准的基本原理――编程语言――C(强调我的):

<块引用>

为了与过去的做法兼容,所有参数提升都发生在在没有原型声明的情况下在 K&R 中描述,包括将浮点数提升为双倍并不总是理想的.

From a previous question:

If you attempt to pass a float to printf, it'll be promoted to double before printf receives it

printf() is a variadic function right? So does a variadic function promote a float argument to a double before passing it?

解决方案

Yes, float arguments to variadic function are promoted to double.

The draft C99 standard section 6.5.2.2 Function calls says:

[...]and arguments that have type float are promoted to double. These are called the default argument promotions.[...]

from the draft C++ standard section 5.2.2 Function call:

[...]a floating point type that is subject to the floating point promotion (4.6), the value of the argument is converted to the promoted type before the call. [...]

and section 4.6:

A prvalue of type float can be converted to a prvalue of type double. The value is unchanged

cppreference covers the default conversions for variadic function in C++ well:

  • std::nullptr_t is converted to void*
  • float arguments are converted to double as in floating-point promotion
  • bool, char, short, and unscoped enumerations are converted to int or wider integer types as in integer promotion

We can see in C and presumably in C++ this conversion was kept around for compatibility with K&R C, from Rationale for International Standard―Programming Languages―C (emphasis mine):

For compatibility with past practice, all argument promotions occur as described in K&R in the absence of a prototype declaration, including the not always desirable promotion of float to double.

相关文章