Лекции.Орг


Поиск:




Категории:

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

 

 

 

 


Проблемы целочисленной машинной арифметики




Несмотря на достоинства в двоичной машинной (аппаратной) арифметике имеются очень неприятные особенности, возникающие из-за конечной разрядности машинной ячейки.

Проблемы сложения положительных чисел

Пусть a=310=00112; b=210=00102; a+b=01012=510, то есть все в порядке.

Пусть теперь a=610=01102, b=510=01012. Тогда a+b =10112= -32.

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

Если у нас беззнаковые целые, проблема остается в несколько измененном виде. Сложим 810+810 в двоичном представлении. Поскольку 810=10002, тогда 810+810= 10002+ 10002=100002. Но лишний бит отбрасывается, и получаем 0. Аналогично в четырёхбитной арифметике, 810+ 910=110, и т.д.

Как уже говорилось, умножение двоичных чисел осуществляется путем сложений и сдвигов по алгоритму, напоминающему умножение “в столбик”, но гораздо более простому, так как умножить надо только на 0 или 1. При целочисленном умножении выход за пределы разрядности ячейки происходит гораздо чаще, чем при сложении или вычитании. Например, 1102 1012=1102 1002+1102 12=110002+1102=111002. Если наша ячейка четырехразрядная, произойдет выход за ее пределы, и мы получим после отбрасывания лишнего бита 11102= -210<0. Таким образом, умножение целых чисел легко может дать неправильный результат. В том числе – даже отрицательное число. Поэтому при работе с целочисленными типами данных следует обращать особое внимание на то, чтобы в программе не возникало ситуаций арифметического переполнения. Повышение разрядности целочисленных переменных позволяет смягчить проблему, хотя полностью её не устраняет. Например, зададим переменные

byte m=10,n=10,k=10;

Тогда значения m*n, m*k и n*k будут лежать в разрешённом диапазоне

-128..127. А вот m*n + m*k из него выйдет. Не говоря уж об m*n*k.

Если мы зададим

int m=10,n=10,k=10;

переполнения не возникнет даже для m*n*k. Однако, при m=n=k=100 значение m*n*k будет равно 106, что заметно выходит за пределы разрешённого диапазона –32768..32767. Хотя m*n, m*k и n*k не будут за него выходить (но уже 4*m*n за него выйдет). Использование типа long поможет и в этом случае. Однако уже значения m=n=k=2000 (не такие уж большие!) опять приведут к выходу m*n*k за пределы диапазона. Хотя для m*n выход произойдёт только при значениях около 50000.

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

Пример:

byte i=127, j=1, k;

k=(byte)(i+j);

System.out.println(k);

В результате получим число (-128). Если бы мы попробовали написать

byte i=127,j=1,k;

System.out.println(i+j);

то получили бы +128. Напомним, что значения величин типа byte перед проведением сложения преобразуются в значения типа int.





Поделиться с друзьями:


Дата добавления: 2017-02-28; Мы поможем в написании ваших работ!; просмотров: 724 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Человек, которым вам суждено стать – это только тот человек, которым вы сами решите стать. © Ральф Уолдо Эмерсон
==> читать все изречения...

2277 - | 2132 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.01 с.