Чи 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 використовують термін "переповнення" для опису результату цілочисельної арифметичної операції, яка має занадто багато бітів, щоб вміститись у тип даних, незалежно від того значення чисельно занадто велике або занадто мало.


* Насправді в C підписане ціле число переповнення насправді є невизначеним поведінкою, але в інших мовах, таких як Java, арифметика доповнення двох буде завершуватися.


6

Це перелив. Для цілих значень не відбувається підтікання.

Переповнення - це те, коли значення занадто велике (занадто далеко від нуля), щоб бути представленим певним типом, а underflwo - коли воно занадто мало (занадто близько до нуля).

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

Стаття Вікіпедії про підводку має досить чіткий опис:

"Термін арифметичний підтік (або" плаваюча точка під підтоком ", або просто" під підтоком ") - умова в комп'ютерній програмі, яка може виникнути, коли справжній результат операції з плаваючою комою менший за величиною (тобто ближче до нуля) ніж найменше значення, представлене як нормальне число з плаваючою точкою в цільовому типі даних. Потоп може частково розцінюватися як негативне переповнення показника значення плаваючої точки ".


Може бути корисним зазначити, що underflowчасто використовується спеціально для позначення конкретної умови, коли величина числа менша, ніж найменшого можливого ненульового значення, але більша за найменшу можливу відстань між ненульовими значеннями - в інших слова, випадки, коли цифри потрапляють у те, що у статті Wiki називається "пробілом". У реалізаціях, сумісних з IEEE-744, найменше представницьке число дорівнює найменшій представній різниці між номерами, тому такі підтоки не можуть відбуватися, але поза межами ПК не всі системи сумісні з IEEE.
supercat

2

У цілій математиці переповнення стосується як занадто великих, так і занадто малих значень. У плаваючій точці переповнення відноситься до занадто великого показника, а під переливом - занадто малий показник.

Насправді для цілих типів процесори не мають можливості визначити різницю між переповненням та переливом. Візьміть наступне 16-бітове додавання:

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

Прапор переповнення в процесорі, звичайно, встановлюється після цього додавання. Використовуючи підписану математику, результат занадто малий (-32768). Використовуючи непідписану математику, результат занадто великий (0x17FFF). Оскільки математика доповнення 2 є однаковою для підписаних і непідписаних типів, overflowзмушена означати як занадто великі, так і занадто малі значення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.