Что такое целочисленная ошибка переполнения? - PullRequest
15 голосов
/ 15 апреля 2010

Что такое целочисленная ошибка переполнения? Почему я забочусь о такой ошибке? Какие есть способы избежать или предотвратить это?

Ответы [ 9 ]

18 голосов
/ 15 апреля 2010

Целочисленное переполнение возникает при попытке выразить число, которое больше, чем наибольшее число, которое может обработать целочисленный тип.

Если вы попытаетесь выразить число 300 в одном байте, у вас переполнение целого числа (максимум 255). 100 000 в двух байтах также является целочисленным переполнением (максимум 65 535).

Вам нужно позаботиться об этом, потому что математические операции не будут работать так, как вы ожидаете. A + B на самом деле не равно сумме A и B, если у вас есть целочисленное переполнение.

Вы избегаете этого, не создавая условие в первую очередь (обычно либо выбирая тип целочисленного типа достаточно большим, чтобы не переполнять, либо ограничивая ввод данных пользователем, чтобы переполнение не происходило). 1007 *

7 голосов
/ 15 апреля 2010

Самый простой способ объяснить это с помощью тривиального примера. Представьте, что у нас есть 4-битное целое число без знака. 0 будет 0000, а 1111 будет 15. Поэтому, если вы увеличите 15 вместо 16, вы вернетесь назад к 0000, поскольку 16 на самом деле составляет 10000, и мы не можем представить это с менее чем 5 битами. Ergo overflow ...

На практике числа намного больше, и при переполнении оно округляется до большого отрицательного числа, если int подписано, но в основном это и происходит.

Еще один способ взглянуть на него - считать его в значительной степени тем же, что происходит, когда одометр в вашем автомобиле снова падает до нуля после того, как пробил 999999 км / ми.

2 голосов
/ 15 апреля 2010

Когда вы сохраняете целое число в памяти, компьютер сохраняет его как последовательность байтов. Они могут быть представлены в виде серии единиц и нулей.

Например, ноль будет представлен как 00000000 (8-битные целые числа), и часто 127 будет представлен как 01111111. Если вы добавите один к 127, это «перевернет» биты и поменяет его на 10000000, но в представлении стандарт два дополняют это фактически используется для представления -128. Это «переполняет» значение.

С числами без знака происходит то же самое: 255 (11111111) плюс 1 станет 100000000, но, поскольку есть только 8 "битов", это заканчивается как 00000000, что равно 0.

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

1 голос
/ 15 апреля 2010

Переполнение - это когда результат арифметической операции не вписывается в тип данных операции. Вы можете переполниться байтовым целым числом без знака, если добавите 255 + 1, потому что результат (256) не помещается в 8 битах байта.

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

Вы также можете иметь underflow с типами с плавающей запятой, когда результат операции с плавающей запятой слишком small для представления в данном типе данных с плавающей запятой. Например, если тип данных с плавающей запятой может обрабатывать показатели в диапазоне от -100 до +100, и вы возводите в квадрат значение с показателем -80, результат будет иметь показатель около -160, который не будет соответствовать заданный тип данных с плавающей запятой.

Вам нужно беспокоиться о переполнениях и недополнениях в вашем коде, потому что он может быть тихим убийцей: ваш код дает неверные результаты, но может не сигнализировать об ошибке.

Возможность безопасного игнорирования переполнений во многом зависит от характера вашей программы - рендеринг пикселов экрана из трехмерных данных имеет гораздо больший допуск к числовым ошибкам, чем, скажем, финансовые расчеты.

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

Сделайте себе одолжение и хотя бы разработайте и протестируйте свой код с включенной проверкой переполнения.

1 голос
/ 15 апреля 2010

Я бы хотел пока немного противоречить всем остальным ответам, которые так или иначе принимают дерьмово сломанную математику как данность. Вопрос помечен как независимый от языка, и в огромном количестве языков целые числа просто никогда не переполняются, поэтому вот мой саркастический ответ:

Что такое целочисленная ошибка переполнения?

Устаревший артефакт из средневековья компьютеров.

почему я забочусь об этом?

Вы не.

как этого избежать?

Используйте современный язык программирования, в котором целые числа не переполняются. (Lisp, Scheme, Smalltalk, Self, Ruby, Newspeak, Ioke, Haskell, выбирайте ...)

1 голос
/ 15 апреля 2010

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

Например, если максимальное значение, которое вы можете иметь, составляет 100000, а текущее значение - 99999, то добавление 2 сделает его «переполнением».

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

0 голосов
/ 15 апреля 2010

С http://www.first.org/conference/2006/papers/seacord-robert-slides.pdf:

Целочисленное переполнение происходит, когда целое число превысило его максимальное значение или снизился за пределы своего минимального значения. Переполнения могут быть подписаны или без знака.

P.S .: В PDF-файле содержится подробное объяснение переполнений и других целочисленных ошибок, а также способов их устранения / предотвращения.

0 голосов
/ 15 апреля 2010

Это происходит, когда вы пытаетесь использовать целое число для значения, которое выше, чем внутренняя структура целого числа, которое может поддерживать из-за количества используемых байтов. Например, если максимальный целочисленный размер равен 2 147 483 647 и вы пытаетесь сохранить 3 000 000 000, вы получите ошибку переполнения целого числа.

0 голосов
/ 15 апреля 2010

Из Википедия :

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

Вы должны быть особенно внимательны при выборе подходящих типов данных для вашей программы, иначе вы можете получить очень тонкие ошибки.

...