是否有一个双重推动等式中的每个int加倍?

时间:2012-12-01 20:40:10

标签: c++ floating-point type-conversion integer-promotion

是否存在一个浮点数据类型(例如double)确保所有+, - ,*,/,%等数学运算都假定为双操作数?

如果故事比这更复杂,是否有描述这些规则的资源?如果等式的结果为int,我是否应该问这些问题并始终明确地将double强制转换为double。这是我正在考虑的一些方程式。我故意不在我的系统上编译和运行,因为这是可能依赖于编译器的类型。

int a(1), b(2), c(3);
double d(4.);
double result1 = a + b/d + c; // equal to 4 or to 4.5?
double result2 = (a + b)/d + c; // equal to 3 or to 3.75?    
double result3 = a/b + d; // equal to 4 or to 4.5?

4 个答案:

答案 0 :(得分:34)

  

我故意不在我的系统上编译和运行,因为这是可能依赖于编译器的类型。

这是编译器相关。 C ++清楚地定义了order of these operations及其转换方式。

转换的发生方式取决于操作顺序。

double result1 = a + b / d + c; // equal to 4 or to 4.5?

在此示例中,首先进行除法。因为这是一个int除以double,编译器通过将int转换为double来处理这个问题。因此,b / d的结果是双倍的。

C ++的下一步是将a添加到b / d的结果中。这是一个添加到double的int,因此它将int转换为double并添加,从而产生double。同样的事情发生在c

double result3 = a / b + d; // equal to 4 or to 4.5?

在此示例中,首先处理除法。 ab都是整数,因此不会进行转换。 a / b的结果是int类型,为0。

然后,将结果添加到d。这是一个int加一个double,所以C ++将int转换为double,结果是double。

即使此表达式中存在double,也会首先计算a / b,而双精度意味着什么,直到执行到达double。因此,会发生整数除法。

我发现促销和转化规则相当复杂。通常类似整数的数字(short,int,long)被提升为浮点数(float,double)。但是尺寸差异和符号使事情变得复杂。

有关转化的详细信息,请参阅this question

答案 1 :(得分:9)

  

一个double是否会将等式中的每个int提升为double

没有。只有单个操作的结果(相对于优先级)。

double result1 = a + b/d + c; // equal to 4 or to 4.5?

4.5。

double result2 = (a + b)/d + c; // equal to 3 or to 3.75?

3.75。

double result3 = a/b + d; // equal to 4 or to 4.5?

4

答案 2 :(得分:2)

您必须考虑每个运算符的优先级,您必须像解析器一样思考:

double result1 = a + b/d + c; // equal to 4 or to 4.5?

这就像一个+(b / d)+ c,因为'/'运算符具有最大的优先级。然后,首先为这两个操作做什么并不重要,因为浮点操作数在中间,它“感染”其他操作数并使它们成为两倍。所以它是4.5。

double result2 = (a + b)/d + c; // equal to 3 or to 3.75?  

在这里,它就像((a + b)/ d)+ c,所以a + b是3,3变成浮点数因为被提升为double,因为是d的被除数,这是一个加倍,所以它是0.75 + 3,即3.75。

double result3 = a/b + d; // equal to 4 or to 4.5?

就像(a / b)+ d,所以a / b为零,d为4,所以它是4。 解析器按优先顺序进行所有操作,因此您可以准确地知道表达式的结果。

答案 3 :(得分:1)

通常,如果二元运算符的一个操作数是浮点而另一个是整数,则整数转换为浮点,结果为浮点。

在具有多个子表达式的复合表达式中,使用您可能知道的优先级规则单独处理每个运算符。因此,在a*b + c*d中,评估a*b,并评估c*d,并将结果相加。 c*d中的任何内容对a*b无效,反之亦然。

当然,C ++很复杂,用户定义的运算符可能还有其他行为。

定义规则的权威资源是C ++标准。该标准非常庞大且技术性强。您可能更愿意首先检查C标准。有关标准的链接,请参阅this answer。任何关于C或C ++的好书都应该描述默认的类型转换和表达式评估。