INT_MIN-1 - это переполнение или переполнение?


10

Кажется, я помню, что читал

  • underflowозначает, что у вас слишком малая величина, которая больше не может быть представлена ​​в виде
  • overflowозначает, что у вас слишком большая величина, которую больше нельзя представить в виде

Однако на практике я понимаю, что термины используются так, что

  • underflowозначает, что у вас слишком маленькое значение, которое больше нельзя представить в виде
  • overflowозначает, что у вас слишком большое значение, которое больше нельзя представить в виде

Какой правильный смысл использовать здесь? Определены ли термины по-разному для целочисленных типов и типов с плавающей точкой?


2
Как правило, термин «недостаточный объем» представляется зарезервированным для арифметики с плавающей запятой. С целыми числами я обычно говорю «переполнение» независимо от того, является ли это INT_MIN - 1илиINT_MAX + 1
Чарльз Сальвия

Ответы:


15

Я действительно не могу найти «авторитетный» источник по этому вопросу, главным образом потому, что это, вероятно, вопрос соглашения, а терминология часто очень противоречива. Но следующая выдержка из « Безопасного кодирования в C и C ++ » Роберта Сикорда подводит итог моего понимания ситуации:

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

Сноска продолжает:

[3] Уменьшение целого числа сверх его минимального значения часто называют целочисленным понижением , хотя технически этот термин относится к условию с плавающей запятой.

Причина, по которой мы называем это целочисленным переполнением, заключается в том, что в типе просто недостаточно места для представления значения. В этом смысле он похож на переполнение буфера (за исключением того, что он фактически не пересекает границу буфера, он обычно демонстрирует поведение циклического перехода. *) С этой точки зрения концептуальной разницы между INT_MIN - 1и нет INT_MAX + 1. В обоих случаях в intтипе данных просто недостаточно места для представления любого значения, поэтому мы имеем переполнение .

Также может быть полезно отметить, что в архитектурах процессоров x86 и x86_64 регистр флагов включает бит переполнения . Бит переполнения устанавливается при переполнении целочисленной арифметической операции со знаком. Выражение INT_MIN - 1установит бит переполнения. (Бита «недополнения» нет.) Очевидно, что инженеры AMD и Intel используют термин «переполнение» для описания результата целочисленной арифметической операции, в которой слишком много битов, чтобы поместиться в тип данных, независимо от того, значение численно слишком велико или слишком мало.


* На самом деле, в С, целочисленное переполнение со знаком является фактически неопределенным поведением, но в других языках, таких как Java, арифметика дополнения двух будет обернута вокруг.


6

Это переполнение. Недостаточное значение не возникает для целочисленных значений.

Переполнение - это когда значение слишком велико (слишком далеко от нуля), чтобы быть представленным конкретным типом, а недостаточное значение - когда оно слишком мало (слишком близко к нулю).

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

Статья на Википедии сгущенного имеет довольно четкое описание:

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


Может быть полезно отметить, что underflowчасто используется специально для ссылки на конкретное условие, где величина числа меньше, чем величина наименьшего возможного ненулевого значения, но больше, чем наименьшее возможное расстояние между ненулевыми значениями - в другом слова, случаи, когда числа попадают в то, что статья в вики называет "разрывом недостаточности". В реализациях, совместимых с IEEE-744, наименьшее представимое число равно наименьшему представимому различию между числами, поэтому такие потери не могут возникнуть, но за пределами мира ПК не все системы соответствуют IEEE-совместимости.
суперкат

2

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

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

  0x8000 (unsigned 32768, or signed -32767)
+ 0xFFFF (unsigned 65535, or signed -1)
--------
  0x7FFF (32767, the carried '1' is lost)

Флаг переполнения в CPU, конечно, будет установлен после этого добавления. При использовании математики со знаком результат слишком мал (-32768). При использовании математики без знака результат слишком велик (0x17FFF). Поскольку математика дополнения 2 идентична для типов со знаком и без знака, overflowона должна означать как слишком большие, так и слишком маленькие значения.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.