不,真的,浮点数促销何时实际发生?

Wan*_*ool 9 c++ floating-point promotions

从另一个问题中,他们谈到了Bjarne Stroustrup如何说,就像整数数据类型比int(例如short)被提升为a一样int,floats被提升为a double.然而,与扩展的扩展不同于扩展int,浮点升级不会以相同的方式发生,而是发生在其他地方.

我知道如果你要计算float + double,float那么在应用double二元运算符(+)之前将转换为a .但是,根据Learncpp.com,这不是浮点促销.这是通常的算术转换.

浮点数促销何时实际发生?

Bri*_*ian 15

有这样的事的"浮点推广" floatdouble每[conv.fpprom.

类型float的prvalue可以转换为类型的prvalue double.该值保持不变.

此转换称为浮点提升.

链接问题的答案是正确的.添加两个floats 时不应自动进行此提升,因为通常的算术转换不会提升浮点操作数.

将作为操作数的操作数传递给省略号时发生浮点提升float,例如printf.这就是为什么%f格式说明符打印a float或a double:如果你传递a float,函数实际接收a double,促销的结果.

浮点升级的存在对于重载决策也很重要,因为积分促销和浮点促销具有比积分转换,浮点转换和浮点积分转换更好的隐式转换等级.

例1:

void f(double);
void f(long double);
f(0.0f);
Run Code Online (Sandbox Code Playgroud)

此调用void f(double)因为促销double比转换为更好long double.相比之下,请考虑这个可能令人惊讶的例子2:

void f(long double);
void f(int);
f(0.0f);
Run Code Online (Sandbox Code Playgroud)

这是模棱两可的.从转换float到的转换long double并不比从转换float到转换更好,int因为它们都不是促销.

例3:

struct S {
    operator float();
    operator int();
};
double d = S();
Run Code Online (Sandbox Code Playgroud)

这会调用operator float然后将结果float值提升double为初始化d.


Jer*_*fin 6

应用浮点促销的主要(可能唯一)时间是将参数传递给可变参数函数(例如printf).

在这种情况下,通常的算术转换不适用(它们用于在表达式中的两个操作数之间查找公共类型).

该标准的相关部分是[expr.call]/7(至少从N4296开始):

当给定参数没有参数时,参数的传递方式使得接收函数可以通过调用va_arg(18.10)来获取参数的值.
[...]
如果参数具有受整数提升(4.5)限制的积分或枚举类型,或者受浮点提升(4.6)影响的浮点类型,则参数的值将转换为在通话前提升类型.