使用来自不同库的相同函数的不同结果
Different results using same function from different libraries
这是一些代码:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long int a, b;
long long int c;
cin >> a >> b;
c = abs(a) + abs(b);
cout << c;
cout << endl;
}
当我输入 1000000000000000000
和 2
.
时应该 return 1000000000000000002
如果我尝试用 cmath
做,它会 return 1000000000000000000
,但如果我用 cstdlib
它会 return 1000000000000000002
.为什么会这样?
另外考虑到我正在使用 cmath,它不是应该工作得更合适吗?
我正在使用 Linux Mint 18.2 64 位,Eclipse 平台。
cmath 版本是 float one。所以当你只有那个时,你实际上是在浮点数上进行计算并在最后转换回 long long
。浮点精度不足以容纳 18 位数字,+2 会丢失。
cstdlib 版本是 integer one。这给出了预期的结果。
正如评论中指出的那样,在 C++11 中,cmath 还定义了一个采用整数的 abs
版本。但是,“这些重载在计算之前有效地将 x 转换为双精度数(为 T 定义为任何整数类型)”。
我相信如果您使用 -Wall -Wextra
或类似的标志而只包含 cmath,您的编译器应该会向您发出转换警告。
如果您使用的是 g++,请尝试使用 -Wconversion
(或 -Wfloat-conversion
)编译两个版本。
请注意,<cmath>
版本会生成警告:
main.cpp:14:7: warning: conversion to ‘long long int’ from ‘__gnu_cxx::__enable_if::__type {aka double}’ may alter its value [-Wfloat-conversion]
c = abs(a) + abs(b);
而 <cstdlib>
版本编译时没有警告。
那是因为,在<cmath>
中,abs()
定义为1:
float abs(float);
double abs(double);
long double abs(long double);
而在<cstdlib>
中定义为1:
int abs(int);
long abs(long);
long long abs(long long);
1自 C++17 起,abs()
的整数版本在 <cmath>
中定义。
这是一些代码:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long int a, b;
long long int c;
cin >> a >> b;
c = abs(a) + abs(b);
cout << c;
cout << endl;
}
当我输入 1000000000000000000
和 2
.
1000000000000000002
如果我尝试用 cmath
做,它会 return 1000000000000000000
,但如果我用 cstdlib
它会 return 1000000000000000002
.为什么会这样?
另外考虑到我正在使用 cmath,它不是应该工作得更合适吗?
我正在使用 Linux Mint 18.2 64 位,Eclipse 平台。
cmath 版本是 float one。所以当你只有那个时,你实际上是在浮点数上进行计算并在最后转换回 long long
。浮点精度不足以容纳 18 位数字,+2 会丢失。
cstdlib 版本是 integer one。这给出了预期的结果。
正如评论中指出的那样,在 C++11 中,cmath 还定义了一个采用整数的 abs
版本。但是,“这些重载在计算之前有效地将 x 转换为双精度数(为 T 定义为任何整数类型)”。
我相信如果您使用 -Wall -Wextra
或类似的标志而只包含 cmath,您的编译器应该会向您发出转换警告。
如果您使用的是 g++,请尝试使用 -Wconversion
(或 -Wfloat-conversion
)编译两个版本。
请注意,<cmath>
版本会生成警告:
main.cpp:14:7: warning: conversion to ‘long long int’ from ‘__gnu_cxx::__enable_if::__type {aka double}’ may alter its value [-Wfloat-conversion] c = abs(a) + abs(b);
而 <cstdlib>
版本编译时没有警告。
那是因为,在<cmath>
中,abs()
定义为1:
float abs(float);
double abs(double);
long double abs(long double);
而在<cstdlib>
中定义为1:
int abs(int);
long abs(long);
long long abs(long long);
1自 C++17 起,abs()
的整数版本在 <cmath>
中定义。