Всем привет.
На Codeforces Round 184 (Div. 2) моё решение взломали из-за переполнения во время умножения. В связи с эти вопрос. Если есть две переменные типа int64, то как проверить, происходит ли переполнение при вычислении a*b?
Всем привет.
На Codeforces Round 184 (Div. 2) моё решение взломали из-за переполнения во время умножения. В связи с эти вопрос. Если есть две переменные типа int64, то как проверить, происходит ли переполнение при вычислении a*b?
| № | Пользователь | Рейтинг |
|---|---|---|
| 1 | Benq | 3676 |
| 2 | Kevin114514 | 3659 |
| 3 | jiangly | 3640 |
| 4 | turmax | 3450 |
| 5 | tourist | 3408 |
| 6 | strapple | 3360 |
| 7 | Um_nik | 3354 |
| 8 | squareOf105 | 3348 |
| 9 | maroonrk | 3312 |
| 10 | idontwannadothis…e | 3191 |
| Страны | Города | Организации | Всё → |
| № | Пользователь | Вклад |
|---|---|---|
| 1 | Qingyu | 154 |
| 2 | nik_exists | 151 |
| 3 | maspy | 149 |
| 4 | AmShZ | 146 |
| 5 | Um_nik | 143 |
| 6 | Errichto | 139 |
| 7 | BledDest | 136 |
| 8 | adamant | 135 |
| 9 | maroonrk | 133 |
| 10 | cry | 130 |
| Название |
|---|



Например, так:
Можно, например, так:
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. И тогда действительно вместо умножения втупую надо писать через деление.