Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Арифметическое переполнение






Арифметическое переполнение (arithmetic overflow) - потеря значащих цифр при вычислении значения выражения.

Если в переменной можно хранить лишь неотрицательные значения (типы BYTE и WORD), то попытка записи в них отрицательного значения не вызовет ошибки. Возникнет арифметическое переполнение и в переменной окажется положительное значение, равное разности между максимально возможным числом комбинаций для этой переменной (256 или 65536 соответственно) и записываемым в нее отрицательным значением. Например, если в переменную a типа BYTE в результате вычислений записывается -20, то реально в ней окажется значение 256-20=236. Аналогичная ситуация возникает при записи слишком больших чисел – значение переменной проходит через ноль и начинает отсчет сначала. Так, при занесении значения 300 в переменную типа BYTE ее значением окажется 300-256=44.

Приведем другой пример: в стандартной настройке компилятор Delphi не вырабатывает код, осуществляющий контроль возможного выхода значения за границы допустимого диапазона, что может привести к недоразумениям. Например, при прогоне следующей программы на экране появится значение 0:

 

procedure TfmExample.bbRunClick(Sender: TObject);

var

k: Word;

 

begin

k: =65535; // Максимальное значение типа Word

k: =k+1; // По правилам математики k=65536

IbOutput.Caption: =IntToStr(k); // На самом деле k=0!

end;

 

Если активизировать переключатель project | options | Compiler | Range checking и повторить компиляцию с помощью Project | Build All, компилятор вставит в программу код проверки переполнения и при прогоне программы возникнет исключительная ситуация, которую при желании можно соответствующим образом обработать. Заметим, что, если изменить программу следующим образом:

 

k: =65535; // Максимальное значение типа Word

//На экран будет выведено значение 65536

IbOutput.Caption: =IntToStr(k+1);

 

переполнения не произойдет, т.к. 32-разрядный компилятор версий Delphi 32 автоматически преобразует операнды выражения k+i к 4-байтным величинам.

 

Еще хуже ситуация складывается при возникновении арифметического переполнения у переменных со знаком – при этом самопроизвольно меняется знак числа.

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

Следующий пример - сложение двух 8-битовых чисел, представленных в двоичном коде, - иллюстрирует этот случай:

  Беззнаковое Знаковое
    +121
    +11
    -124
    (неправильно)

Сложение положительных чисел никогда не дает в результате отрицательного числа.

Результат сложения оказался непредставимым в диапазоне значений 8-битовых чисел в двоичном коде (от -128 до +127).

Также возможен случай одновременного арифметического переполнения беззнакового и знакового чисел:

  Беззнаковое Знаковое
    -10
    -119
    +127
  (неправильно) (неправильно)

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.