Czy INT_MIN-1 jest niedopełnieniem lub przepełnieniem?

10

Wydaje mi się, że pamiętam, że to czytałem

  • underflowoznacza, że ​​masz zbyt małą wielkość , której nie można już przedstawić w typie
  • overflowoznacza, że ​​masz zbyt dużą jasność , której nie można już przedstawić w typie

Jednak w praktyce uważam, że terminy są używane w taki sposób

  • underflowoznacza, że ​​masz zbyt małą wartość , której nie można już przedstawić w typie
  • overflowoznacza, że ​​masz zbyt dużą wartość , której nie można już przedstawić w typie

Jakie jest właściwe znaczenie tutaj? Czy terminy są zdefiniowane inaczej dla typów liczb całkowitych i zmiennoprzecinkowych?

Johannes Schaub - litb
źródło
2
Ogólnie rzecz biorąc, termin „niedomiar” wydaje się być zarezerwowany dla arytmetyki zmiennoprzecinkowej. Z liczb całkowitych, zwykle mówią „overflow”, niezależnie od tego, czy jest to INT_MIN - 1alboINT_MAX + 1
Charles Salvia

Odpowiedzi:

15

Naprawdę nie mogę znaleźć „autorytatywnego” źródła w tej sprawie, głównie dlatego, że jest to prawdopodobnie kwestia konwencji, a terminologia jest często bardzo niespójna. Ale poniższy fragment „ Bezpiecznego kodowania w C i C ++ ” Roberta Seacorda podsumowuje moje rozumienie sytuacji:

Przepełnienie liczb całkowitych występuje, gdy liczba całkowita zostanie zwiększona powyżej wartości maksymalnej lub zmniejszona powyżej wartości minimalnej 3 . Przepełnienia liczb całkowitych są ściśle powiązane z podstawową reprezentacją.

Przypis mówi dalej:

[3] Zmniejszenie liczby całkowitej powyżej jej minimalnej wartości jest często określane jako niedomiar liczby całkowitej , chociaż technicznie termin ten odnosi się do warunku zmiennoprzecinkowego.

Powodem, dla którego nazywamy to przepełnieniem liczb całkowitych, jest to, że po prostu nie ma wystarczającej ilości miejsca w typie do przedstawienia wartości. W tym sensie jest podobny do przepełnienia bufora (z wyjątkiem faktycznego przekroczenia granicy bufora, zwykle wykazuje zachowanie zawijania. *) Z tej perspektywy nie ma różnicy koncepcyjnej między INT_MIN - 1a INT_MAX + 1. W obu przypadkach po prostu nie ma wystarczającej ilości miejsca w inttypie danych, aby reprezentować którąkolwiek wartość - więc mamy przepełnienie .

Warto również zauważyć, że w architekturach procesorów x86 i x86_64 rejestr flag zawiera bit przepełnienia . Bit przepełnienia jest ustawiany, gdy przepełniona zostanie arytmetyczna operacja ze znakiem całkowitym. Wyrażenie INT_MIN - 1ustawi bit przepełnienia. (Nie ma bitu „niedopełnienia”.) Tak więc wyraźnie inżynierowie AMD i Intela używają terminu „przepełnienie” do opisania wyniku operacji arytmetycznej na liczbach całkowitych, która ma zbyt wiele bitów, aby zmieścić się w typie danych, niezależnie od tego, czy wartość jest liczbowo za duża lub za mała.


* W rzeczywistości w C podpisane przepełnienie liczb całkowitych jest w rzeczywistości nieokreślonym zachowaniem, ale w innych językach, takich jak Java, arytmetyka dopełniania tych dwóch elementów zostanie zawinięta.

Charles Salvia
źródło
6

To przelew. Niedopełnienie nie występuje w przypadku wartości całkowitych.

Przepełnienie występuje, gdy wartość jest zbyt duża (zbyt daleko od zera), aby mogła być reprezentowana przez określony typ, a niedopełnienie występuje, gdy jest zbyt mała (zbyt blisko zera).

Ponieważ wartości liczbowe najbliższe zeru (1 i -1) mogą być nadal reprezentowane przez dowolną zmienną całkowitą (zakładając, że liczba całkowita ze znakiem jest większa niż jeden bit), niedopełnienie nie może wystąpić.

Artykuł w Wikipedii na temat niedomiaru ma dość jasny opis:

„Termin niedopełnienie arytmetyczne (lub„ niedopełnienie zmiennoprzecinkowe ”lub po prostu„ niedopełnienie ”) to warunek w programie komputerowym, który może wystąpić, gdy prawdziwy wynik operacji zmiennoprzecinkowej jest mniejszy (tj. Bliższy zeru) niż najmniejsza wartość reprezentowana jako normalna liczba zmiennoprzecinkowa w docelowym typie danych. Niedopełnienie można częściowo uznać za przepełnienie ujemne wykładnika wartości zmiennoprzecinkowej. ”

Guffa
źródło
Warto zauważyć, że underflowczęsto stosuje się go konkretnie w odniesieniu do konkretnego warunku, w którym wielkość liczby jest mniejsza niż najmniejsza możliwa wartość niezerowa, ale większa niż najmniejsza możliwa odległość między wartościami niezerowymi - w innych słowa, przypadki, w których liczby mieszczą się w tym, co artykuł Wiki nazywa „luką niedomiaru”. W implementacjach zgodnych z IEEE-744 najmniejsza reprezentowalna liczba równa się najmniejszej reprezentatywnej różnicy między liczbami, więc takie niedopełnienia nie mogą wystąpić, ale poza światem komputerów PC nie wszystkie systemy są zgodne z IEEE.
supercat
2

W matematyce całkowitej przepełnienie odnosi się zarówno do zbyt dużych, jak i zbyt małych wartości. W zmiennoprzecinkowym przepełnienie odnosi się do zbyt dużego wykładnika, a niedopełnienie odnosi się do zbyt małego wykładnika.

W rzeczywistości dla typów całkowitych procesory nie mają możliwości odróżnienia przepełnienia od niedopełnienia. Weź następujące 16-bitowe dodanie:

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

Flaga przepełnienia w procesorze zostałaby oczywiście ustawiona po tym dodaniu. Przy użyciu matematyki ze znakiem wynik jest za mały (-32768). Przy użyciu matematyki bez znaku wynik jest za duży (0x17FFF). Ponieważ matematyka uzupełnienia 2 jest identyczna dla typów podpisanych i niepodpisanych, overflowmusi oznaczać zarówno zbyt duże, jak i zbyt małe wartości.

Uwaga do samodzielnego wymyślenia imienia
źródło