我在C和C++上编程已经有一段时间了,一直确定双倍除以int得到双倍,或者双倍除以int也得到双倍(只有int乘以int得到int),加法也是如此。我在做作业时,确信 1 + (f*f + 10) / k
,其中 f
是 double
和 k
是 int
总是会返回双倍。g++ -std=gnu++11
命令(所以可能是clang编译器),我得到了测试通过的结果(我确实得到了浮点数),但我的老师说,它不确定会是浮点数(他使用的是windows)。这种行为是平台特有的吗?有没有什么C++标准来描述double对int除法?谢谢!我的代码。
#include <iostream>
using namespace std;
int main() {
int N;
double f, P = 0;
cin >> N >> f;
for (double k = 1; k <= N; k++){
P += 1 + (f*f + 10) / k;
}
cout << P;
return 0;
}
摘自C++20标准草案 [expr.arith.conv]:
许多期望操作数为算术或枚举类型的二进制运算符以类似的方式引起转换并产生结果类型。其目的是产生一个共同的类型,也就是结果的类型。这种模式称为通常的算术转换,其定义如下。
- (1.1)如果任一操作数是范围枚举类型,则不进行转换;如果另一操作数没有相同的类型,则表达式不规范。
- (1.2)如果任一操作数为长双类型,则另一操作数应转换为长双。
- (1.3)否则,如果任一操作数为double,则另一操作数应转换为double。
- (1.4)否则,应将另一操作数转换为长双。如果其中一个操作数是float,另一个操作数将被转换为float。.
- (1.5)否则,应在两个操作数上进行积分推广([conv.prom]).56然后对推广的操作数应用以下规则:......。
这段内容至少从C++11开始(这是我查到的最老的版本)就没有任何基金化的变化,所以你的老师要做一些解释。
如你所见 此处:
[...]如果任何一个操作数是双数,则另一个操作数转换为双数。
[...]如果其中一个操作数是float,则另一个操作数转换为float。
所以它的标准保证了该操作会给你回一个 float
如果一个表达式包含两个参数,其中一个是 double
另一个是 int
,那么该表达式的类型总是一个 double.
如果一个表达式包含两个参数,其中一个是 float
另一个是 int
,那么该表达式的类型总是一个 float.
在许多方面,第二种说法已经变得不合时宜(因为64位的 int
也许就在眼前)。) 请注意,在您的代码段中,您使用的是一个叫做 double
而非 float
.
一些模板元编程代码(!)给老师看。
#include <iostream>
#include <type_traits>
int main(){
// Will output 1 if the types are the same, 0 otherwise
std::cout << std::is_same<decltype(int{} + double{}), double>::value;
}
在这里你可以替换 double
和 int
与您自己选择的类型进行比较:代码所做的是将类型的 int{} + double{}
与 double
.