Всем привет.
На Codeforces Round 184 (Div. 2) моё решение взломали из-за переполнения во время умножения. В связи с эти вопрос. Если есть две переменные типа int64, то как проверить, происходит ли переполнение при вычислении a*b?
Всем привет.
На Codeforces Round 184 (Div. 2) моё решение взломали из-за переполнения во время умножения. В связи с эти вопрос. Если есть две переменные типа int64, то как проверить, происходит ли переполнение при вычислении a*b?
№ | Пользователь | Рейтинг |
---|---|---|
1 | jiangly | 3846 |
2 | tourist | 3799 |
3 | orzdevinwang | 3706 |
4 | jqdai0815 | 3682 |
5 | ksun48 | 3590 |
6 | Ormlis | 3533 |
7 | Benq | 3468 |
8 | Radewoosh | 3463 |
9 | ecnerwala | 3451 |
9 | Um_nik | 3451 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 165 |
2 | -is-this-fft- | 161 |
3 | Qingyu | 160 |
4 | atcoder_official | 156 |
4 | Dominater069 | 156 |
6 | adamant | 154 |
7 | djm03178 | 151 |
8 | luogu_official | 149 |
9 | Um_nik | 148 |
10 | awoo | 147 |
Название |
---|
Например, так:
Можно, например, так:
c = a * b;
if (c / a != b) {
// переполнение
}
Или так: log(a) + log(b) > log(INF)
Приведённые выше примеры либо могут быть неточными (
double
), либо со знаковыми типами вызывают неопределённое поведение (c = a * b
).Если числа неотрицательные, то проверить можно примерно так:
Однако полезность такой проверки мне представляется сомнительной. Допустим, что логика решения этой проверки не требует и нам нужно вывести как раз это
a * b
. Теперь мы вставляем проверку и на каком-то тесте обнаруживаем потенциальное переполнение. И что теперь делать, раз ответ всё равно не вычислен? С таким же успехом можно и вообще не проверять. Вывод: надо просто писать решение так, чтобы возможность переполнения никогда не возникала.Зато не так редко возникает ситуация, когда в коде
if(a*b<=n)...
значения переменных a, b и n порядка 1018. И тогда действительно вместо умножения втупую надо писать через деление.