Арифметические операции над действительными числами с фиксированной точкой
Запись данных в запоминающем устройстве ЭВМ. Умножение без переполнения и потери точности. Превышение числом разрядности 32 бита. Преимущества и недостатки использования фиксированной точки. Автоматическая "фильтрация" пренебрежимо малых значений.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | реферат |
Язык | русский |
Дата добавления | 29.09.2012 |
Размер файла | 20,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ И НАУКЕ
Федеральное государственное автономное образовательное учреждение
высшего профессионального образования
«СЕВЕРО-КАВКАЗСКИЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»
РЕФЕРАТ
«Арифметические операции над действительными числами с фиксированной точкой»
Выполнила: студентка 3 курса
специальности «ПМиИ» группы А
Чемерисова М.Ю.
Преподаватель: доц. Макоха А.Н.
Ставрополь 2012
Введение
При проектировании ЭВМ, создании инструментального и прикладного программного обеспечения разработчикам приходится решать вопрос о представлении в ЭВМ числовых данных. Для решения большинства прикладных задач обычно достаточно использовать целые и вещественные числа. Запись целочисленных данных в запоминающем устройстве ЭВМ не представляет затруднений: число переводится в двоичную систему и записывается в прямом коде. Диапазон представляемых чисел в этом случае ограничивается количеством выделенных для записи разрядов. Для вещественных данных обычно используются две формы записи: число с фиксированной точкой и число с плавающей точкой. Мы рассмотрим числа с фиксированной точкой
В вычислительной математике дробные значения представляют в виде пары целых чисел (n, e): мантиссы и экспоненты (по-русски более верно «показателя степени», но для краткости и по привычке буду в дальнейшем употреблять именно слово «экспонента»). Пара представляет дробное число в виде n * 2e.
Экспоненту можно рассматривать как количество цифр перед запятой, отделяющей дробную часть числа.
Если экспонента переменная, записываемая в регистр и неизвестная при компиляции, (n, e) называют числом с плавающей запятой. Если экспонента известна заранее, (n, e) называют числом с фиксированной точкой. Числа с фиксированной точкой могут записываться в обыкновенные целочисленные переменные (регистры) путем сохранения только мантиссы. Экспоненту обычно обозначают буквой q. Так что, встретив в комментарии к переменной что-нибудь в духе "q15 multiplier", следует рассматривать эту переменную как число с фиксированной точкой и экспонентой, равной 15.
Вычисления
Итак, при работе с фиксированной точкой экспонента нигде не записывается и держится «в уме».
Как же производить расчеты? Вычислительная арифметика -- целая наука со своими формулами, аксиомами и теоремами. Целью данной статьи не было давать введение в эту науку. Подходы, приведенные ниже, в первую очередь ориентированы на программистов, решающих инженерные и прикладные задачи, т.е. такие, где диапазоны допустимых значений и необходимые точности вычислений известны и ограничены.
1. Сложение и вычитание
Сложение выполняется просто, если представить в уме, что мы должны сложить две десятичные дроби «в столбик» на листе бумаги. При выполнении данной операции числа записываются в столбик так, чтобы запятые, отделяющие дробную часть, располагались одна под другой. В двоичной арифметике подобная операция называется приведением экспонент.
Если перейти от «бумажки» к математической записи, получится следующее:
Пусть имеется два числа
a = n1 * 2q1 и b = n2 * 2q2.
Тогда:
a + b = n1 * 2q1 + n2 * 2q2 = (n1 + n2 * 2(q1 -- q2))*2q1.
Множитель 2(q1 -- q2) при втором слагаемом по сути означает арифметический сдвиг для приведения чисел к одной экспоненте.
Стоит отметить, что результат вычисления также может сдвигаться для приведения к требуемому значению экспоненты.
Фрагмент кода на С:
int32_t a = 0x1000L; // q15: a = 0.125
int32_t b = 0x20000L; // q20: b = 0.125
int32_t c = 0; // q25
c = (a << 5) + b; // q20: (a * 2 ^ (20 - 15) + b); c = 0x40000L (0.25 в q20)
c <<= 5; // q25: c = 0x800000L (0.25 в q25)
Из примера может быть понятно, что в реальных вычислениях даже в такой простой операции как сложение, есть простор для раздумий. Всегда стоит держать в уме вопросы:
· жертвовать точностью или нет? Можно ведь привести слагаемые к меньшей экспоненте сдвигом вправо и отбросить младшие разряды.
· ограничены ли значения переменных? Сдвиг вправо в данном случае, например, не приводит к потере точности.
· есть ли возможность расширить разрядность?
Это далеко не полный список, но уже показывает, что не все так просто, как может показаться на первый взгляд. В большинстве практических применений для каждой предметной области известны или могут быть получены диапазоны допустимых значений, так что при работе с фиксированной точкой требуется некоторый опыт или проведение исследований. Зачастую предварительно код пишется с плавающей запятой, после чего исследуются диапазоны значений, и малыми значениями пренебрегают.
2. Умножение
Умножение с фиксированной точкой может выполняться без хитрых выравниваний и приведения к единой экспоненте. Тем не менее умножение -- достаточно опасная операция, которая чаще всего в итоге приводит к потере точности и требует особой аккуратности в обращении.
Начнем с математического описания умножения:
Пусть имеется два числа
a = n1 * 2q1 и b = n2 * 2q2.
Тогда:
a * b = n1 * 2q1 * n2 * 2q2 = n1 * n2 * 2(q1 + q2).
Из выражения видно, что экспоненты чисел при умножении складываются: 2(q1 + q2). Разрядность данных в этой статье не рассматривается, пока достаточно лишь запомнить, что для безопасного умножения без переполнения и потери точности разрядность результата должна быть не меньше суммарной разрядности сомножителей.
Из-за сложения экспонент результат умножения приходится корректировать для выполнения дальнейших вычислений. При уменьшении экспоненты младшие разряды результата отбрасываются. То есть происходит потеря точности. Можно уменьшить потери точности (и иногда приходится), но способы борьбы с потерями всегда связаны с накладными расходами.
Фрагмент кода на С:
int32_t a = 0x8000L; // q15: a = 0.5
int32_t b = 0x100000L; // q20: b = 0.5
int32_t c = 0xC0000L; // q20: c = 0.75
int64_t d; // Временная переменная с увеличенным числом разрядов, чтобы хватило на результат.
d = (int64_t)a * (int64_t)b; // q35 = q15 * q20; d = 0x800000000L (0.25 in q35)
d >>= 15; // q35 / 2 ^ 15 = q20
c += (int32_t)d; // q20: c = 0x100000 (1 in q20)
Отмечу, что 15 младших разрядов результата умножения были отброшены, чтобы привести число к формату слагаемого. Можно было, конечно, увеличить разрядность переменной c, но, как я уже говорил, на практике диапазоны значений обычно ограничены и младшими разрядами умножения зачастую пренебрегают. Кроме того, не учитывается возможность наличия в исходных сомножителях ненулевых старших разрядов.
Но в данной статье обработка переполнений не рассматривается.
3. Деление
Начнем с математического выражения для деления:
Пусть имеется два числа
a = n1 * 2q1 и b = n2 * 2q2.
Тогда:
a / b = n1 * 2q1 / (n2 * 2q2) = n1 / n2 * 2(q1-q2)
Сомножитель 2(q1-q2) означает, что при выполнении деления экспонента автоматически уменьшается. Если не принять меры, часть значащих разрядов отбрасывается автоматически.
Способ коррекции очевиден -- необходимо заранее увеличить разрядность делителя настолько, чтобы в результате деления получить желаемое количество значащих бит:
a / b = n1 * 2q1 * 2q3 / (n2 * 2q2) = n1 / n2 * 2(q1-q2+q3).
Таким образом, экспонента частного увеличена на q3 разряда.
Фрагмент кода на С:
int32_t a = 0x8000L; // q15: a = 0.5
int32_t b = 0x100000L; // q20: b = 0.5
int32_t c = 0; // q25
int64_t d; // Временная переменная с увеличенным числом разрядов.
d = (int64_t)a << 30; // q45: d = 0x200000000000; (0.5 in q45)
c = (int32_t)(d / (int64_t)b); // q25: c = 0x2000000; (1 in q25)
Очевидно, что при превышении числом разрядности 32 бита, проблему уже не решить так просто. Тем не менее, для простых инженерных расчетов 32-битных чисел обычно более, чем достаточно.
Есть один простой способ значительно сократить потерю точности при делении -- предварительное нормирование делимого. Нормирование -- фактически максимальный сдвиг мантиссы влево, при котором не происходит отбрасывания значащих битов.
Заключение
умножение точность разрядность значение фильтрация
О плюсах и минусах использования фиксированной точки
Наиболее распространенными являются два варианта обозначения числа с фиксированной точкой:
1. QM -- где M -- число разрядов после запятой. Использована в статье
2. QN.M -- где N -- число разрядов до запятой без учета знакового бита, а M -- после.
Минус первой нотации очевиден: при работе с переменной приходится обращаться к объявлению переменной (вспоминать ее разрядность) и производить в уме некоторые вычисления, чтобы понять, как привести экспоненту к желаемой. Больше того, если вспомнить округление (int32_t)d в примере с умножением, можно отметить, что при комментариях в данной нотации сложно понять, приведет ли сдвиг или отбрасывание значащих битов к ошибке.
При использовании комментариев во второй нотации можно просто записывать точность вычислений, что исключает необходимость вспоминать, как объявлена переменная.
Столь подробное описание даже для базовых операций способно отпугнуть инженеров и программистов от использования фиксированной точки в вычислениях, особенно, если уже выработана привычка к плавающей запятой без слежения за результатом. Тем не менее, в использовании фиксированной точки есть свои плюсы, некоторые из которых неочевидны.
Для того, чтобы окончательно определиться, надо ли оно вам, можно использовать следующую сводку по вычислениям с фиксированной точкой.
Плюсы:
· Необходимость думать.
· Предсказуемость результата. При правильном подходе к кодированию результат вычислений будет одинаков на любой платформе (процессор + компилятор) с точностью до разряда. Для данного явления существует специальный термин «битэкзактность» (от англ., bit-exactness). Правильно закодированный алгоритм всегда битэкзактен и, следовательно, может исследоваться на нецелевой платформе. Особенно это полезно, когда отладка на целевой платформе затруднена или невозможна и можно снять только входные данные.
· Полный контроль за поведением кода. Фиксированная точка исключает появление «неожиданностей», связанных с особенностями реализации плавающей запятой на используемой платформе.
· Автоматическая «фильтрация» пренебрежимо малых значений. В плавающей запятой ошибки вычислений могут накапливаться, в фиксированной точке этого не происходит (за счет отбрасывания малых значений) или процесс накопления ошибок можно контролировать алгоритмически.
· Алгоритмически контролируемый диапазон значений переменных. Плавающая запятая дает больше свободы в вычислениях, но результат может выходить за пределы допустимых, что приводит к необходимости его контролировать отдельно. В фиксированной точке эта проблема решается автоматически на этапе разработки и отладки алгоритма.
· Переносимость алгоритмов. Данный плюс изрядно коррелирует с первым, но стоит отметить, что целочисленные вычисления гораздо лучше поддержаны множеством не-х86 процессоров, чем вычисления с плавающей запятой. Так что, разработав один раз алгоритм в фиксированной точке, портировать его на различные «слабые» платформы становится гораздо проще. Иногда целочисленные вычисления вообще единственное, что доступно на целевой платформе.
· Возможность контролировать сложность вычислений путем понижения точности при разработке алгоритма.
· Иногда это интересно.
Минусы:
· Необходимость думать.
· Пониженный (в простейшем случае) диапазон значений переменных по сравнению с плавающей запятой.
· Необходимость алгоритмически контролировать диапазон значений переменных. Значительная часть времени при разработке уходит на правильное масштабирование и выбор диапазонов.
· Необходимость следить за разрядностью на каждом этапе вычислений.
· Необходимость писать собственный фреймворк базовых функций (тригонометрических, логарифмических и т.п.) или модифицировать существующий.
· Необходимость погружаться в прикладную область при разработке алгоритма.
· Необходимость повышать культуру написания и поддержки кода -- без использования собственных наработок в фиксированной точке не обойтись. В плавающей точке чаще всего можно, не задумываясь, переписать математику «в лоб», с использованием готовых функций.
Размещено на Allbest.ru
Подобные документы
Типы численных данных с фиксированной точкой и основные операции обращения с ними. Целые двоичные числа: классификация, особенности, основные понятия. Наработка практических навыков обращения с целыми числами на компьютере (запись, считывание, хранение).
контрольная работа [24,8 K], добавлен 12.03.2011Выполнение операции умножения над числами с фиксированной точкой со сдвигом суммы частичных произведений вправо. Разработка структуры центрального процессора при выполнении двухадресной команды со следующими способами адресации: прямая и регистровая.
курсовая работа [459,5 K], добавлен 25.03.2012Двоично-десятичный формат (BCD - Binary Coded Decimal). Преобразование ASCII формата в двоичный формат. Арифметические инструкции и флаги. Форматы арифметических данных. Выполнение арифметических операции. Сложение. Вычитание. Умножение. Деление.
доклад [16,2 K], добавлен 22.09.2008Операции, осуществляемые при реализации алгоритмов цифровой обработки сигналов. Применение процессора ADSP-2106x для операций с фиксированной и плавающей точкой. Исключения при выполнении операций с плавающей точкой, режимы и границы округления.
реферат [35,2 K], добавлен 13.11.2009Числа с фиксированной точкой характеризуются длиной слова в битах, положением двоичной точки, бывают беззнаковыми или знаковыми. Позиция двоичной точки определяет число разрядов в целой и дробной частях машинного слова. Представление отрицательного числа.
лабораторная работа [156,7 K], добавлен 31.05.2009Основные форматы данных и их представление. Запись чисел в формат с плавающей точкой. Вычитание чисел в формате с плавающей точкой. Регистры операндов и результата, размером формата числа с плавающей точкой, двойной точности. Поля смещённого порядка.
курсовая работа [78,9 K], добавлен 09.09.2014Числа с фиксированной точкой характеризуются длиной слова в битах, положением двоичной точки, бывают беззнаковыми или знаковыми. Позиция двоичной точки определяет число разрядов в целой и дробной частях машинного слова. Представление отрицательного числа.
лабораторная работа [154,6 K], добавлен 31.05.2009Изучение методов и этапов создания класса Complex, позволяющего работать с комплексными числами и производить с ними следующие операции: сложение, вычитание, умножение, деление двух комплексных чисел. Написание кода для ввода и вывода исходных данных.
курсовая работа [628,4 K], добавлен 11.09.2010Разработка устройства, выполняющее следующие операции: загрузку операндов, алгебраическое вычитание чисел с фиксированной точкой в модифицированных дополнительных кодах и выдачу результата. Функциональная микропрограмма работы операционного устройства.
курсовая работа [2,7 M], добавлен 14.02.2012Арифметические операции с целыми числами. Сложение и вычитание в дополнительном коде. Представление чисел в формате с плавающей точкой. Особенности выполнения арифметических операций в соответствии с IEEE. Точность выполнения арифметических операций.
контрольная работа [5,6 M], добавлен 19.05.2010