Главная » Просмотр файлов » М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)

М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781), страница 29

Файл №1160781 М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)) 29 страницаМ. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781) страница 292019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 29)

Аппаратная и программная плавающая точка

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

Компьютер без соответствующих аппаратных средств может все же выпол­нять вычисления с плавающей точкой, используя библиотеку подпрограмм, которые эмулируют (emulate) команды с плавающей точкой. Попытка выпол­нить команду с плавающей точкой вызовет прерывание «несуществующая ко­манда», которое будет обработано с помощью вызова соответствующей под­программы эмуляции. Само собой разумеется, что это может быть очень не­эффективно, поскольку существуют издержки на прерывание и вызов под­программы, не говоря о самом вычислении с плавающей точкой.

Если вы предполагаете, что ваша программа будет активно использоваться на компьютерах без аппаратной поддержки плавающей точки, может быть ра­зумнее совсем ей не пользоваться и явно запрограммировать вычисления с фиксированной точкой. Например, финансовая программа может делать все вычисления в центах вместо долей доллара. Конечно, при этом возникает риск переполнения, если типы Integer или Long_integer не представлены с до- статочной точностью.

Смешанная арифметика

В математике очень часто используются смешанные арифметические опера­ции с целыми и вещественными числами: мы пишем А = 2pi*r, а не А = 2.0pi*r. При вычислении смешанные операции с целыми числами и числами с плава­ющей точкой должны выполняться с некоторой осторожностью. Предпочти­тельнее вторая форма, потому что 2.0 можно хранить непосредственно как константу с плавающей точкой, а литерал 2 нужно было бы преобразовать к представлению с плавающей точкой. Хотя обычно это делается компилято­ром автоматически, лучше точно написать, что именно вам нужно.

Другой потенциальный источник затруднений — различие между целочис­ленным делением и делением с плавающей точкой:

Ada

I: Integer := 7;

J: Integer := I / 2;

К: Integer := lnteger(Float(l) / 2.0);

Bыражение в присваивании J задает целочисленное деление; результат, ко-нечно, равен 3. В присваивании К требуется деление с плавающей точкой: ре-зультат равен 3.5, и он преобразуется в целое число путем округления до 4.

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

int i = 7;

C

int j = i/2;

int k = (int) ((float i)/ 2.0);

Здесь 3 присваивается как j, так и k, потому что значение 3.5 с плавающей точкой обрезается, а не округляется!

В языке С неявно выполняется смешанная арифметика, в случае необхо­димости целочисленные типы преобразуются к типам с плавающей точкой, а более низкая точность к более высокой. Кроме того, значения неявно преоб­разуются при присваивании. Таким образом, вышеупомянутый пример мож­но было бы написать как

C

int k = i/2.0;

«Продвижение» целочисленного i к плавающему типу вполне распознаваемо, и тем не менее для лучшей читаемости программ в присваиваниях (в отличие от инициализаций) преобразования типов лучше задавать явно:

C

k=(int)i/2.0;

В Ada вся смешанная арифметика запрещена; однако любое значение число­вого типа может быть явно преобразовано в значение любого другого число­вого типа, как показано выше.

Если важна эффективность, реорганизуйте смешанное выражение так, чтобы вычисление оставалось по возможности простым как можно дольше. Рассмотрим пример (вспомнив, что литералы в С рассматриваются как dou­ble):

C

int i,j,k,l; float f= 2.2 * i * j * k * I;

Здесь было бы выполнено преобразование i к типу double, затем умножение 2.2 * i и так далее для каждого целого числа, преобразуемого к типу double. Наконец, результат был бы преобразован к типу float. Эффективнее было бы написать:

C


int i j, k, I; I

float f=2.2F*(i*J*k*l);

чтобы гарантировать, что сначала будут перемножены целочисленные пере­менные с помощью быстрых целочисленных команд и что литерал будет хра­ниться как float, а не как double. Конечно, такая оптимизация может привести к целочисленному переполнению, которого могло бы не быть, если вычисле­ние выполнять с двойной точностью.

Одним из способов увеличения эффективности любого вычисления с пла­вающей точкой является изменение алгоритма таким образом, чтобы только часть вычислений должна была выполняться с двойной точностью. Напри­мер, физическая задача может использовать одинарную точность при вычис­лении движения двух объектов, которые находятся близко друг от друга (так что расстояние между ними можно точно представить относительно неболь­шим количеством цифр); программа затем может переключиться на двойную точность, когда объекты удалятся друг от друга.

9.3. Три смертных греха

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

  • исчезновение операнда,

  • умножение ошибки,

  • потеря значимости.

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

0.1234 х 103 + 0.1234 х 10-4 = 0.1234 х 103

Маловероятно, что преподаватель средней школы учил вас, что х + у = х для ненулевого у, но именно это здесь и произошло!

Умножение ошибки — это большая абсолютная ошибка, которая может появиться при использовании арифметики с плавающей точкой, даже если относительная ошибка мала. Обычно это является результатом умножения деления. Рассмотрим вычисление х • х:

0.1234 х103 • 0.1234 х 103 = 0.1522 х 105

и предположим теперь, что при вычислении х произошла ошибка на единицу младшего разряда, что соответствует абсолютной ошибке 0.1:

0.1235 х 103 • 0.1235 х 103 = 0.1525 х 105

Абсолютная ошибка теперь равна 30, что в 300 раз превышает ошибку перед умножением.

Наиболее грубая ошибка — полная потеря значимости, вызванная вычита­нием почти равных чисел:

C


float f1= 0.12342;

float f2 = 0.12346;

B математике f2 -f1 = 0.00004, что, конечно, вполне представимо как четы­рехразрядное число с плавающей точкой: 0.4000 х 10-4. Однако программа, вы-числяющая f2 - f 1 в четырехразрядном представлении с плавающей точкой, даст ответ:

0.1235 10°-0.1234x10° = 0.1000 х 10-3

что даже приблизительно не является приемлемым ответом.

Потеря значимости встречается намного чаще, чем можно было бы пред­положить, потому что проверка на равенство обычно реализуется вычитанием и последующим сравнением с нулем. Следующий условный оператор, та­ким образом, совершенно недопустим:

C

f2=...;

f2=…;

if (f1 ==f2)...

Самая невинная перестройка выражений для f 1 и f2, независимо от того, сде­лана она программистом или оптимизатором, может вызвать переход в услов­ном операторе по другой ветке. Правильный способ проверки равенства с плавающей точкой состоит в том, чтобы ввести малую величину:

C

#define Epsilon10e-20

if ((fabs(f2-f1))<Epsilon)...

и затем сравнить абсолютное значение разности с малой величиной. По той же самой причине нет существенного различия между < = и < при вычислени­ях с плавающей точкой.

Ошибки в вычислениях с плавающей точкой часто можно уменьшить изменением порядка действий. Поскольку сложение производится слева на­право, четырехразрядное десятичное вычисление

1234.0 + 0.5678 + 0.5678 = 1234.0

лучше делать как:

0.5678 + 0.5678 + 1234.0 = 1235.0

чтобы не было исчезновения слагаемых.

В качестве другого примера рассмотрим арифметическое тождество:

(х+у)(х-у)=х22

и используем его для улучшения точности вычисления:

X, Y: Float_4;

Z: Float_7;

Ada

Z := Float_7((X + Y)*(X - Y)); -- Так считать?

Z := Float_7(X*X - Y*Y); -- или так?

Если мы положим х = 1234.0 и у = 0.6, правильное значение этого выражения будет равно 1522755.64. Результаты, вычисленные с точностью до восьми цифр, таковы:

(1234.0 + 0.6) • (1234.0-0.6) =1235.0 • 1233.0=1522755.0

и

(1234.0 • 1234.0)-(0.6 • 0.6) = 1522756.0-0.36 =1522756.0

При вычислении (х + у) (х- у) небольшая ошибка, являющаяся результа­том сложения и вычитания, значительно возрастает при умножении. При вычислении по формуле х2 - у2 уменьшается ошибка от исчезновения слагаемого и результат получается более точным.

    1. Вещественные типы в языке Ada

Замечание: техническое определение вещественных типов было значи­тельно упрощено при переходе от Ada 83 к Ada 95, поэтому, если вы предпо­лагаете детально изучать эту тему, лучше опускать более старые определе­ния.

Типы с плавающей точкой в Ada

В разделе 4.6 мы описали, как можно объявить целочисленный тип, чтобы по­лучить данный диапазон, в то время как реализация выбирается компилято­ром:

type Altitude is range 0 .. 60000;

Аналогичная поддержка переносимости вычислений с плавающей точкой обеспечивается объявлением произвольных типов с плавающей точкой:

type F is digits 12;

Это объявление запрашивает точность представления из 12 (десятичных) цифр. На 32-разрядном компьютере для этого потребуется двойная точность, тогда как на 64-разрядном компьютере достаточно одинарной точности. Об- ратите внимание, что, как и в случае целочисленных типов, это объявление создает новый тип, который нельзя использовать в операциях с другими типа-ми без явных преобразований.

Стандарт Ada подробно описывает соответствующие реализации такого Объявления. Программы, правильность которых зависит только от требо-ваний стандарта, а не от каких-либо причуд частной реализации, гаран-тированно легко переносимы с одного компилятора Ada на другой, даже на [компилятор для совершенно другой архитектуры вычислительной сис-темы.

Типы с фиксированной точкой в Ada

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

type F is delta 0.1 range 0.0 .. 1.0;

Кроме диапазона при записи объявления типа с фиксированной точкой ука-зывается требуемая абсолютная погрешность в виде дроби после ключевого слова delta.

Заданные delta D и range R означают, что реализация должна предоставить набор модельных чисел, отличающихся друга от друга не больше чем на D и по­крывающих диапазон R. На двоичном компьютере модельные числа были бы кратными ближайшего числа, меньшего D и являющегося степенью двойки, в нашем случае 1/16 = 0.0625. Данному выше объявлению соответствуют следу­ющие модельные числа:

О, 1/16, 2/16,..., 14/16,15/16

Обратите внимание, что, даже если 1.0 определена как часть диапазона, это число не является одним из модельных чисел! Определение только требует, чтобы 1.0 лежала не далее 0.1 от модельного числа, и это требование выполня­ется, потому что 15/16 = 0.9375 и 1.0 — 0.9375 < 0.1.

Существует встроенный тип Duration, который используется для измере­ния временных интервалов. Здесь подходит тип с фиксированной точкой, по­тому что время будет иметь абсолютную погрешность (скажем 0.0001 с) в за­висимости от аппаратных средств компьютера.

Для обработки коммерческих данных в Ada 95 определены десятичные ти­пы с фиксированной точкой.

type Cost is delta 0.01 digits 10;

В отличие от обычных типов с фиксированной точкой, которые представля­ются степенями двойки, эти числа представляются степенями десяти и, та­ким образом, подходят для точной десятичной арифметики. Тип, объявлен­ный выше, может поддерживать значения до 99999999.99.

9.5. Упражнения

1. Какие типы с плавающей точкой существуют на вашем компьютере? Пе­речислите диапазон и точность представления для каждого типа. Ис­пользуется ли смещение в представлении экспоненты? Выполняется ли нормализация? Есть ли скрытый старший бит? Существует ли представ­ление бесконечности или других необычных значений?

2. Напишите программу, которая берет число с плавающей точкой и печа­тает знак, мантиссу и экспоненту (после удаления всех смещений).

3. Напишите программу для целочисленного сложения и умножения с не­ограниченной точностью.

Характеристики

Тип файла
Документ
Размер
2,54 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6439
Авторов
на СтудИзбе
306
Средний доход
с одного платного файла
Обучение Подробнее