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

时间:2015-05-27 18:40:00

标签: c++ floating-point promotions

从其他QUESTION他们谈到Bjarne Stroustrup如何表示,正如将int(例如short)更窄的整数数据类型提升为intfloat被提升为double。但是,与扩展比int更窄的积分不同, 浮点促销 不会以相同的方式发生,而是发生在其他地方。

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

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

2 个答案:

答案 0 :(得分:13)

有这样的事情"浮点促销"每[conv.fpprom] floatdouble

  

类型float的prvalue可以转换为double类型的prvalue。价值没有变化。

     

此转换称为浮点促销。

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

float作为操作数传递给省略号时会发生 ,就像在printf中一样。这就是%f格式说明符打印floatdouble的原因:如果您传递float,该函数实际上会收到double ,促销的结果。

浮点升级的存在对于重载决策也很重要,因为积分促销和浮点促销具有比积分转换更好的隐式转换排名< / em>,浮点转换和浮动积分转换

示例1:

void f(double);
void f(long double);
f(0.0f);

这会调用void f(double),因为促销double优于转化为long double。相比之下,请考虑这个可能令人惊讶的例子2:

void f(long double);
void f(int);
f(0.0f);

这是含糊不清的。从floatlong double的转换并不比从floatint的转换更好,因为它们都不是促销。

示例3:

struct S {
    operator float();
    operator int();
};
double d = S();

这会调用operator float,然后将生成的float值提升为double,以初始化d

答案 1 :(得分:6)

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

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

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

  

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