我有以下c ++代码:
#include <iostream>
using namespace std;
int main()
{
long long int currentDt = 467510400*1000000;
long long int addedDt = 467510400*1000000;
if(currentDt-addedDt >= 0 && currentDt-addedDt <= 30*24*3600*1000000)
{
cout << "1" << endl;
cout << currentDt-addedDt << endl;
}
if(currentDt-addedDt > 30*24*3600*1000000 && currentDt-addedDt <= 60*24*3600*1000000)
{
cout << "2" << endl;
cout << currentDt-addedDt << endl;
}
if(currentDt-addedDt > 60*24*3600*1000000 && currentDt-addedDt <= 90*24*3600*1000000)
{
cout << "3" << endl;
cout << currentDt-addedDt << endl;
}
return 0;
}
首先,我得到一个整数溢出的警告,这让我感到奇怪,因为数字467510400 * 1000000完全落在长long int的范围内,不是吗?其次,我得到以下输出:
1
0
3
0
如果在两种情况下currentDt-addedDt的计算结果为0,那么第三个if语句怎么可能评估为true?
答案 0 :(得分:5)
467510400*1000000
在long long
范围内,但不在int
范围内。由于两个文字都是int
类型,因此产品的类型也是int
类型 - 并且会溢出。仅仅因为您将结果分配给long long
并不会更改分配的值。出于同样的原因:
double d = 1 / 2;
d
将保留0.0
而非0.5
。
您需要明确地将其中一个文字强制转换为更大的整数类型。例如:
long long int addedDt = 467510400LL * 1000000;
答案 1 :(得分:0)
long long int currentDt = 467510400ll*1000000ll;
long long int addedDt = 467510400ll*1000000ll;
请注意数字后面的两个小写字母“l”。这些使你的常数很长。 C ++通常将源中的数字字符串解释为普通int
s。
答案 2 :(得分:0)
您遇到的问题是所有整数文字都是int
。当你将它们相乘时,它们会溢出,给你意想不到的行为。要解决此问题,您可以使用long long
467510400ll * 1000000ll
文字
答案 3 :(得分:0)
因为
60*24*3600*1000000 evaluates to -25526272
使用
60LL*24LL*3600LL*1000000LL
而是(请注意&#39; LL&#39;后缀)
答案 4 :(得分:0)
您已使用C ++标记此内容。
我对代码的最小更改将使用c ++ static_cast将至少一个文字数字(任何溢出生成表达式)提升为int64_t(在包含文件cstdint中找到)。
示例:
// 0 true
if(currentDt-addedDt >= 0
&& // true because vvvv
// 0 true
currentDt-addedDt <= 30*24*3600*static_cast<int64_t>(1000000))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(对于测试1,if子句的结果为true。 对于测试2和3是错误的)
找到static_cast后,编译器会将其他3个整数(在子句中)提升为int64_t,因此不会生成有关溢出的警告。
是的,它在某种意义上增加了许多字符,“最小”。