据我了解,当 s2
较大时,s1.size() - s2.size()
会下溢,因为它是 unsigned
的减法。
为什么将它们转换为 int
不会导致整数减法?
为什么转换整个事情会给我正确的结果?我期望它评估括号内的内容,然后下溢,这将给出一个大数字,然后转换为 int 不会产生任何影响。我错过了什么?
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
bool isShorter(const string &s1, const string &s2) {
return (static_cast<int>(s1.size()) - s2.size() < 0) ? true : false; // underflows
//return (static_cast<int>(s1.size() - s2.size()) < 0) ? true : false; // this works
}
int main() {
string s, t;
getline(cin, s);
getline(cin, t);
cout << "s: " << s << endl;
cout << "t: " << t << endl;
cout << "printing shorter string of the two..." << endl;
cout << ((isShorter(s, t)) ? s : t) << endl;
}
最佳答案
当你这样做时
static_cast<int>(s1.size()) - s2.size()
您转换s1.size()
到 int
然后当你减去s2.size()
时由此可知int
提升为与 s2.size()
相同的类型然后将其减去。这意味着您仍然需要进行无符号整数减法,并且由于它永远不会是负数,因此它会环绕到更大的数字。这和做s1.size() - s2.size()
没有什么不同。 .
你也有同样的事情
static_cast<int>(s1.size() - s2.size())
还有可能有符号整数溢出的额外好处,这是未定义的行为。您仍在进行无符号整数减法,因此如果 s1
小于 s2
比你绕到一个大数字。
您需要做的是将 s1.size()
都转换为和s2.size()
转换为有符号整数类型以获得有符号整数减法。这可能看起来像
static_cast<ptrdiff_t>(s1.size()) - static_cast<ptrdiff_t>(s2.size())
现在如果 s1.size()
你实际上会得到一个负数小于s2.size()
.
需要注意的是,所有这些都可以通过使用小于运算符来避免。您的函数可以重写为
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
恕我直言,这更容易阅读和理解。
关于c++ - 为什么 static_cast 减法会溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42700609/