ViKo 1 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба Хочу в static_assert проверять оговоренное в заголовке условие. Как-то логарифмы сложить? Но не вижу, что получится точно. К примеру, 7 * 4 = 28, а 7 * 7 = 49. Результат оккупирует разное количество битов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 2 минуты назад, ViKo сказал: Хочу в static_assert проверять оговоренное в заголовке условие. Как-то логарифмы сложить? Но не вижу, что получится точно. К примеру, 7 * 4 = 28, а 7 * 7 = 49. Результат оккупирует разное количество битов. Из этого следует что максимальные перемножаемые числа должны быть не больше корня квадратного из максимально возможного результата. Само собой это без знака. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба static_assert((sizeof(x) + sizeof(y)) <= sizeof(z))); z = x * y Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 1 минуту назад, MegaVolt сказал: Из этого следует что максимальные перемножаемые числа должны быть не больше корня квадратного из максимально возможного результата. Само собой это без знака. Не следует. Можно 0x1FFF'FFFF'FFFF'FFFF умножить на 2. 1 минуту назад, Forger сказал: Да вроде как достаточно, чтобы множители были соотв. не больше половины байтов от результата: static_assert((sizeof(x) + sizeof(y)) <= sizeof(z))) z = x * y Не достаточно. Мне с точностью до бита нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 16 минут назад, ViKo сказал: Не достаточно. Мне с точностью до бита нужно. а так ? static_assert(((x) * (y)) > (x))); // и тоже самое для "y" суть в том, что если было переполнение то произведение будет меньше одного из чисел Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 2 минуты назад, megajohn сказал: static_assert(((x) (y)) <= (z))); А что здесь написано, поясните, пожалуйста. 4 минуты назад, megajohn сказал: static_assert(((x) * (y)) > (x)+(y))); x * y уже может переполнить uint64_t, никак не сигнализируя. С чем и столкнулся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 2 минуты назад, ViKo сказал: А что здесь написано, поясните, пожалуйста. почему-то знаки пропадали после публикации. Выше поправил Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 16 минут назад, megajohn сказал: суть в том, что если было переполнение то произведение будет меньше одного из чисел О, это интересно! static_assert((x * y) >= x && (x * y) >= y)); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба static_assert((long double)x*y > ULLONG_MAX, "Overflow!"); Не? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба Цитата static_assert((x * y) >= x && (x * y) >= y)); только при условии что оба числа беззнаковые или одного знака ( -3 * 5 = -15; -15<-3 <5) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 7 минут назад, Edit2007 сказал: только при условии что оба числа беззнаковые Да, без. 9 минут назад, Arlleex сказал: static_assert((long double)x*y > ULLONG_MAX, "Overflow!"); Не? Видимо, да. Только сами x, y в double перевести. А, как раз x и переводится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 53 минуты назад, ViKo сказал: Не следует. Можно 0x1FFF'FFFF'FFFF'FFFF умножить на 2. Не достаточно. Мне с точностью до бита нужно. Ну если всё так серьёзно то для того чтобы проверbть что x*y<z нужно z разделить на x и проверить что результат больше y. Т.е. условие y<z/x Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба Умножаю 1000'000'000'000 на 16'000'000 - ассерт Arllexx срабатывает. Умножаю 10000'000'000'000 на 16'000'000 - уже нет. Метод, предложенный MegaVolt - работает! static_assert((UINT64_MAX / y) > x, "Over!"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 13 минут назад, ViKo сказал: Метод, предложенный MegaVolt - работает! static_assert((UINT64_MAX / y) > x, "Over!"); только не забыть проверить на ноль Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 25 14 февраля, 2020 Опубликовано 14 февраля, 2020 · Жалоба 6 минут назад, megajohn сказал: только не забыть проверить на ноль Да. Но если не усложнять то для положительных чисел можно просто к y добавить некоторую дельту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться