Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/146: Рейтинг темы: голосов - 146, средняя оценка - 4.90
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564

Как отловить переполнение границ типа (INT)?

23.02.2015, 04:07. Показов 31534. Ответов 69
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сразу напишу пример для наглядности:
C++
1
2
3
4
5
int fx = -2147483648
if(fx == -fx)
{
 //ляляля
}
В 32 битах максимум и минимум int имеет границы: -2147483648 до 2147483647, в показанном примере естественным образом должна была бы быть ошибка(хотя бы уведомление), но его нет... Как отлавливать такие вот не корректные моменты?

И это лишь один момент из интересующих который выведет не верный результат...
Ещё один:
C++
1
2
3
int fx = 2147483646
int fy = 20;
int fz = fx+fy;
Как бороться?..
Читал что некоторые создают особый тип (эквивалентный например 64 битному), т.к. границы будут дальше, то и результат можно будет сравнить полученное число с текущим, однако всё же границы останутся (теперь на пороге 64 битного числа), и подобный метод не подойдёт, т.к. за границы всё равно может выйти число. Так как в арифметических операциях предотвратить подобное?
П.С. желательно чтоб примеры\инфа была бы применима в динамических переменных, т.е. на этап уже запуска без среды программирования. (собственно из уже получившейся программы)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.02.2015, 04:07
Ответы с готовыми решениями:

отловить переполнение типа данных
Здравствуйте:) У меня возник вопрос по сабжу. допустим мы присваиваем переменной типа double что-нибудь такое : 0,7e-50000...

Как обойти переполнение int?
как обойти переполнение integer'а ? Например...

Напишите перегруженную функцию power (), которая принимает два целочисленных параметра типа int и возвращает целочисленное значение типа int
Операции над целыми числами осуществляются быстрее, чем над числами с плавающей точкой. Напишите перегруженную функцию power (), ...

69
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
23.02.2015, 13:39
Студворк — интернет-сервис помощи студентам
nmcf, насчет менее убогой системы типов - я слышал краем уха, что какие-то Си-компиляторы последнее время позволяют задавать целый тип любой разрядности в байтах. Что могу сказать - давно пора. А насчет "громоздкого умножения и деления" - не более "громоздкое", чем реализация оного для интов на 8-битных платформах - те же последовательные однобайтовые операции. А вспоминая мой недавний нудёж про возможное отсутствие мулов и дивов в списке аппаратных инструкций и тем не менее реализацию компилятором и умножения и деления многобайтовых типов - вышеупоминаемая "громоздкость" не добавляет никакого качественного усложнения концепции.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
23.02.2015, 13:43
Громоздкость будет в записи этого на ассемблере.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.02.2015, 13:58
Цитата Сообщение от nmcf Посмотреть сообщение
Громоздкость будет в записи этого на ассемблере.
Если смотреть на машинный код, if(res>100500) будет еще более громоздким. Другое дело что оно будет легко переносимым на другую платформу. И не будет геморрою с ручным распределением регистров, которых на x86 чуть больше чем нифига (вроде, на более современных процессорах поправили). Но все равно обидно что не предусмотрели штатных средств контроля арифметического переполнения.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.02.2015, 14:07
Цитата Сообщение от Renji Посмотреть сообщение
все равно обидно что не предусмотрели штатных средств контроля арифметического переполнения.
Как вы это себе вообще представляете?
Вы осознаете какую цену придется заплатить за подобного рода проверки?

Кому нужно - могут склепать какой нибудь класс чисел с проверками и исключениями.

Но в том, что касается фундаментального int,
стандарт языка напротив стремится максимально оптимизировать вычисления.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.02.2015, 14:23
Цитата Сообщение от hoggy Посмотреть сообщение
Как вы это себе вообще представляете?
1) try_arithmetic_overflow секция внутри которой арифметическое переполнение кидает исключение. За пределами секции - переполнение игнорируется.
2) Ключевое слово arithmetic_flags дающее прямой доступ к процессорным флагам содержащим данные о результате последней арифметической операции. Ну да, с оговорками про ухудшение оптимизации и зависимость реализации от платформы.
3) Синтаксическое правило по которому int*int="как удобно процессору" (вообще-то, 32-битовое на 32-битовое внутри x86 дает 64-битовое. Он его по двум 32-битовым регистрам распихивает). Опять же, черт с ними, с оговорками про зависимость от платформы.
Цитата Сообщение от hoggy Посмотреть сообщение
Кому нужно - могут склепать какой нибудь класс чисел с проверками и исключениями.
С неимоверно кривыми потрохами. Потому как у этого класса все равно не будет доступа к аппаратным средствам контроля переполнения.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
23.02.2015, 14:51
Цитата Сообщение от Renji Посмотреть сообщение
С неимоверно кривыми потрохами. все равно не будет доступа к аппаратным средствам контроля переполнения.
Почему с кривыми? Ну будут вычисления с int производиться в long long. Можно ассемблерные вставки сделать, если очень хочется.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.02.2015, 15:12
Цитата Сообщение от Renji Посмотреть сообщение
1) try_arithmetic_overflow секция внутри которой арифметическое переполнение кидает исключение. За пределами секции - переполнение игнорируется.
такое решение вроде нормально вписывается.
хотя сама практика - плодить ключевые слова для обработки частных случаев немного напрягает.
поскольку неизбежно влечет за собой разбухание ключевых слов языка.

Грубо говоря, если узаконить try_arithmetic_overflow, то это создаст прецедент,
и захочется узаконить ещё 100500 разных ключевых слов под разные ситуативные моменты.

Цитата Сообщение от Renji Посмотреть сообщение
3) Синтаксическое правило по которому int*int="как удобно процессору"
В настоящий момент оно итак действует.

В стандарте языка это называется "промоушен типов".
Сложение двух short даст int, например.

4.5 Integral promotions [conv.prom]
1 A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all
the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned
int.
Пример:

http://rextester.com/KNZN1500

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
int main()
{
    std::cout << "Hello, world!\n";
    
    typedef decltype(short() + short()) sum;
    
    if( is_same<sum, int>::value == 1 )
        cout<<"decltype( short()+short() ) is int"<<endl;
    
    short v1 = 0;
    short v2 = 0;
    
    if( is_same<decltype(v1 +v2), int>::value == 1 )
        cout<<"decltype( v1+v2 ) is int"<<endl;
    
    auto v3 = v1+v2;
    
    if( is_same<decltype(v3), int>::value == 1 )
        cout<<"decltype( v3 ) is int"<<endl;
 
}
Цитата Сообщение от Renji Посмотреть сообщение
(вообще-то, 32-битовое на 32-битовое внутри x86 дает 64-битовое. Он его по двум 32-битовым регистрам распихивает)
32 битное на 32 битное может дать 64 битное, только если sizeof(int) есть 64 битное.

Промоушен действуют только на те модификаторы,
чей эффект даёт sizeof меньше, чем sizeof(int).

Это означает, что перемножение двух int всегда даст int независимо от его размера.

А объясняется это тем, что sizeof(int) - это и есть "как удобно процессору"

Добавлено через 2 минуты
Цитата Сообщение от Renji Посмотреть сообщение
С неимоверно кривыми потрохами. Потому как у этого класса все равно не будет доступа к аппаратным средствам контроля переполнения.
такие вещи - это утилитарные классы общего назначения.

им место где нибудь в std/boost.

и их не велосипедят заново под очередную платформу.

для их создания не нужно ничего менять в существующем языке.

мой посыл: сопровождение и потроха таких инструментальных средств - это не проблема его пользователей.
Это проблема - разработчика. А сделать можно. Технически это все вполне себе реализуется.
0
 Аватар для saden
184 / 168 / 53
Регистрация: 27.01.2013
Сообщений: 788
23.02.2015, 15:17
http://www.fefe.de/intof.html
http://netcode.ru/cpp/?click=r.php-393.htm
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.02.2015, 15:18
Цитата Сообщение от hoggy Посмотреть сообщение
Это означает, что перемножение двух int всегда даст int независимо от его размера.
Разъясняю на пальцах. Процессор перемножает числа с помощью команды IMUL. Команда IMUL умножает 32-битовый регистр EAX на 32-битовый регистр на выбор программиста. Результат же помещается в два 32-битовых регистра EDX:EAX. Теперь приходит компилятор, говорит "а система то 32 битовая" и выкидывает EDX (старшие 32 бита результата). А надо чтоб не умничал и возвращал все 64 бита.
Цитата Сообщение от nmcf Посмотреть сообщение
Почему с кривыми?
Потому что на ассемблере контроль переполнения реализуется одной командой jo (перейти по метке если произошло переполнение). Все что превышает одну команду jo - криво по определению.

Что касается ассемблерных вставок, они скорее всего всю оптимизацию кода порушат. Грубо говоря, компилятор хотел положить переменную в регистр EAX. Но так как ассемблерная вставка ничего о желаниях компилятора не знает, пришлось класть переменную в память. Иначе как ассемблер до нее доберется?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.02.2015, 15:23
Цитата Сообщение от Renji Посмотреть сообщение
Разъясняю на пальцах. Процессор перемножает числа с помощью команды IMUL. Команда IMUL умножает 32-битовый регистр EAX на 32-битовый регистр на выбор программиста. Результат же помещается в два 32-битовых регистра EDX:EAX. Теперь приходит компилятор, говорит "а система то 32 битовая" и выкидывает EDX (старшие 32 бита результата). А надо чтоб не умничал и возвращал все 64 бита.
Я на самом деле не силен в ассемблере.
Точно не знаю, что там происходит.

Знаю только, что промоушен типов специально для того и существует,
что бы оптимизировать по разрядной сетке машины.

А это означает, что получать 64 бита вместо 32 там, где 32 - это sizeof(int) - не эффективно.
0
 Аватар для saden
184 / 168 / 53
Регистрация: 27.01.2013
Сообщений: 788
23.02.2015, 15:26
мне больше всего понравился вариант:
при условии, что А и В не переполняют инт:
C++
1
if(MAX_INT-A > B) {будет переполнение}
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
23.02.2015, 15:28
Цитата Сообщение от Renji Посмотреть сообщение
Процессор перемножает числа с помощью команды IMUL. Команда IMUL умножает 32-битовый регистр EAX на 32-битовый регистр на выбор программиста. Результат же помещается в два 32-битовых регистра EDX:EAX.
а кроме х86 других архитектур нету?
и каким переходом отлавливать переполнение не разрядной сетки, а диапазона чисел
типа
C++
1
2
3
char a=127;
char b=127;
char c=a+b;// -2
переполнения разрядной сетки нет, но мы залезли в область отрицательных чисел
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.02.2015, 15:54
Цитата Сообщение от hoggy Посмотреть сообщение
А это означает, что получать 64 бита вместо 32 там, где 32 - это sizeof(int) - не эффективно.
Да нет, просто такая поддержка 64 битовой арифметики кастрированная. Умножение, сложение только в 32 битах. Деление позволяет использовать 64-бита как делимое, но результат все равно будет 32-битовым. Для описания всех этих ограничений придется вводить какой ни будь stupid_long_int.
Цитата Сообщение от ValeryS Посмотреть сообщение
а кроме х86 других архитектур нету?
Потому и написал - "int*int=как удобно процессору". Если процессор умеет умножать с повышением разрядности числа - пользуемся этим. Не умеет - ну, что поделать.
Цитата Сообщение от ValeryS Посмотреть сообщение
и каким переходом отлавливать переполнение не разрядной сетки, а диапазона чисел
jo и отлавливать. Флаг переполнения устанавливается при выходе за диапазон знакового числа. А то о чем вы подумали - флаг переноса.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
23.02.2015, 17:00
Цитата Сообщение от Renji Посмотреть сообщение
Грубо говоря, компилятор хотел положить переменную в регистр EAX
Ну так ты же и предлагаешь jo и прочее для оптимизации, куда ещё оптимизировать, если оформить как функцию?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.02.2015, 17:09
Цитата Сообщение от Renji Посмотреть сообщение
Да нет, просто такая поддержка 64 битовой арифметики кастрированная.
Поддержка 64 битных зависит от процессора.
Если он такое поддерживает, то ничего не мешает перемножать/складывать/делить 64 битные числа.
Если вам это нужно - пожалуйста.

Другое дело, что в 99,(9)% всех случаев, 32 битного типа данных вполне достаточно
для операций над 32битными числами.
И это работает эффективно.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
23.02.2015, 17:11
Renji, плюсанул вам за некоторый рефреш моей памяти и при этом отсутствие придирок к моим неточностям в этой связи
ЗЫ вся тема напоминает историю проверок выхода за границы массивов и цену которой за это платится. Реализовано во многих языках, делается гораздо проще контроля диапазона целых чисел, и то жрет ресурсы и в Сях летает быстрее потому что всех этих проверок нет. Но при всем при этом, компилятор мог бы быть более юзер-френдли и давать доступ к регистру состояний с джампом по меткам и управляемым поведением при арифметических операциях - специально для тех, кто хочет залезть руками и настроить под себя.
0
26 / 26 / 18
Регистрация: 16.01.2014
Сообщений: 161
23.02.2015, 17:18
Ну, если уж очень хотите знать, то посмотрите класс Integer в JDK. Там есть метод, чтобы уловить переполнение, если я правильно помню.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.02.2015, 17:45
Цитата Сообщение от nmcf Посмотреть сообщение
Ну так ты же и предлагаешь jo и прочее для оптимизации, куда ещё оптимизировать, если оформить как функцию?
Я предлагаю тем или иным образом сказать компилятору "проверяй переполнение". А он уже пускай jo и расставляет. Если делать через функции, нужно как минимум иметь прямой доступ к флагам процессора (он туда хомячит "переполнилось/не переполнилось"). А это опять же будет изменением синтаксиса языка.
Цитата Сообщение от hoggy Посмотреть сообщение
Другое дело, что в 99,(9)% всех случаев, 32 битного типа данных вполне достаточно
Ну да, а потом оказывается что бывают файлы больше четырех гигабайт, жизнь после 2038 года (unix-time) и геймер-Вася скопивший 2 147 483 648 фантиков. Если логика программы допускает арифметическое переполнение, кто ни будь его да устроит.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
23.02.2015, 18:15
Цитата Сообщение от Izual Посмотреть сообщение
Как отлавливать такие вот не корректные моменты?
Их не надо отлавливать. Их просто не надо допускать.
1
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
23.02.2015, 18:57  [ТС]
Цитата Сообщение от castaway Посмотреть сообщение
Их не надо отлавливать. Их просто не надо допускать.
Цитата Сообщение от Renji Посмотреть сообщение
геймер-Вася скопивший 2 147 483 648 фантиков
Надо. И желательно чтоб холивар в теме плавно перетёк в точные подсказки по теме, понятные не только тем кто тут 24\7 холиварит))) (было занятно почитать конешно, но всё это на столько глубоко копается, что толку от вашего холивара лишь "моя кобыла быстрее", а мне нужно просто чтоб работало, и желательно "просто")
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.02.2015, 18:57

Передать массив элементов(типа int) объекта, в функцию из массивов(типа int)
Представьте такую ситуацию. Есть у вас массив чисел: Mass И вы хотите передать его в функцию. Я делаю это так: //объявим ф-ю: ...

Как передать 0 в функцию типа f (int, int&)
Подскажите, почему при повторных вызовах f остается предыдущее значение S? Т.е. не обнуляется в теле f - {...s=0...} и как его обнулить?...

Значение типа int нельзя присвоить сущности типа int
значение типа int нельзя присвоить сущности типа int подскажите с исправлением ошибки ст 26.27 #include&lt;stdio.h&gt; #include...

Значения типа int нельзя присвоить сущности типа int
Значения типа int нельзя присвоить сущности типа int. Как изменить код, что бы было правильно? #include &lt;iostream&gt; #include...

Как сравнить переменную типа String с переменной типа Int?
Как сравнить переменную типа String с переменной типа Int в конструкции &quot;if&quot;???


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru