是否存在一个浮点数据类型(例如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?
答案 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?
在此示例中,首先处理除法。 a
和b
都是整数,因此不会进行转换。 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 ++的好书都应该描述默认的类型转换和表达式评估。