網上的很多代碼都是錯的,我來hack一波
因為UB的問題,很多代碼看起來是對的,但是在O2或者別的情況下很容易出問題
c\c++的補碼溢出是UB,但無符號溢出不是UB
注意這樣的細節,不然很容易翻車
https://www.cnblogs.com/klzwj1988/archive/2011/09/12/2174134.html
hack數據 10,INT32_MIN
原因:沒有處理-INT32_MIN未定義的情況,大多數情況下-INT32_MIN = -INT32_MIN,直接死循環
https://blog.csdn.net/weixin_30670151/article/details/96988831
hack數據 INT32_MIN,10
原因:條件不對
常見判斷有符號乘法溢出的問題
1.a * b == INT_MIN 當a取INT32_MIN,很容易出問題,正確的姿勢是用除法來判斷乘法溢出
2.INT32_MIN / a 當a = -1的時候,直接乘法溢出....很多代碼都沒有考慮到這個情況....
3.一般情況-INT32_MIN = INT32_MIN,很多人在化負數為整數的時候,沒有考慮到這一點....
吐槽
網上一堆代碼抄來抄去....錯誤的很多...吐了
hack數據
兩層for暴力枚舉check即可,數據很強
using ll = long long int;
vector<ll> v = {10,10,INT64_MAX,INT64_MIN,0,INT32_MAX,INT32_MIN,100,-100,INT32_MAX / 2,INT32_MIN / 2,INT64_MAX / 2,INT64_MIN / 2,3,-3,-INT64_MAX,-1,1,2,-2,-3,-10,1ll * INT32_MAX * (INT32_MAX - 10),1ll * INT32_MAX * INT32_MAX * 1ll,1ll * INT32_MIN * INT32_MAX,123456789101112ll,-1234567891234578ll-1234568,12345645,123544515555ll,1ll * INT32_MIN / INT32_MAX,1ll * INT32_MAX * 123454,1ll * INT32_MIN * 1231121,12313,INT32_MIN / 8 * 1ll - 100,1ll * INT32_MIN * 8 * 1ll + 1};
正確的代碼
#include <numeric>
#include <iostream>
#include <algorithm>
template<typename T,typename T2>
bool is_mul_overflow(T a,T2 b) {
static_assert(std::is_same<T,T2>::value,"is_mul_overflow[類型不匹配]");
using std::numeric_limits;
if (a == -1) {
return (b == numeric_limits<T>::min());
}
else if (b == -1) {
return (a == numeric_limits<T>::min());
}
else if (a >= 0 and b >= 0) {
return a == 0 ? 0 : numeric_limits<T>::max() / a < b;
}
else if(a < 0 and b < 0) {
return numeric_limits<T>::max() / a > b;
}
else if (b < 0) {
return numeric_limits<T>::min() / b < a;
}
else {
return numeric_limits<T>::min() / a < b;
}
}
int main() {
std::cout << is_mul_overflow(10,500000000);
return 0;
}