Плавающей операции точкой с: Что нужно знать про арифметику с плавающей запятой / Хабр

Содержание

Наглядное объяснение чисел с плавающей запятой / Хабр

В начале 90-х создание трёхмерного игрового движка означало, что вы заставите машину выполнять почти не свойственные ей задачи. Персональные компьютеры того времени предназначались для запуска текстовых процессоров и электронных таблиц, а не для 3D-вычислений с частотой 70 кадров в секунду. Серьёзным препятствием стало то, что, несмотря на свою мощь, ЦП не имел аппаратного устройства для вычислений с плавающей запятой. У программистов было только АЛУ, перемалывающее целые числа.

При написании книги Game Engine Black Book: Wolfenstein 3D я хотел наглядно показать, насколько велики были проблемы при работе без плавающей запятой. Мои попытки разобраться в числах с плавающей запятой при помощи каноничных статей мозг воспринимал в штыки. Я начал искать другой способ. Что-нибудь, далёкое от и их загадочных экспонент с мантиссами. Может быть, в виде рисунка, потому что их мой мозг воспринимает проще.

В результате я написал эту статью и решил добавить её в книгу. Не буду утверждать, что это моё изобретение, но пока мне не приходилось видеть такого объяснения чисел с плавающей запятой. Надеюсь, статья поможет тем, у кого, как и у меня, аллергия на математические обозначения.


Как обычно объясняют числа с плавающей запятой

Цитирую Дэвида Голдберта (David Goldbert):

Для многих людей арифметика с плавающей запятой кажется каким-то тайным знанием.

Полностью с ним согласен. Однако важно понимать принципы её работы, чтобы полностью осознать её полезность при программировании 3D-движка. В языке C значения с плавающей запятой — это 32-битные контейнеры, соответствующие стандарту IEEE 754. Они предназначены для хранения и выполнения операций над аппроксимациями вещественных чисел. Пока я видел только такое их объяснение. 32 бита разделены на три части:

  • S (1 бит) для хранения знака
  • E (8 бит) для экспоненты
  • M (23 бита) для мантиссы


Внутренности числа с плавающей запятой.


Три части числа с плавающей запятой.

Пока всё нормально. Пойдём дальше. Способ интерпретации чисел обычно объясняется с помощью такой формулы:

Именно это объяснение чисел с плавающей запятой все ненавидят.

И здесь я обычно начинаю терять терпение. Возможно, у меня аллергия на математическую нотацию, но когда я это читаю, в моём мозгу ничего не «щёлкает». Такое объяснение похоже на способ рисования совы:

Другой способ объяснения

Хоть это изложение и верно, такой способ объяснения чисел с плавающей запятой обычно не даёт нам никакого понимания. Я виню эту ужасную запись в том, что она разочаровала тысячи программистов, испугала их до такой степени, что они больше никогда не пытались понять, как же на самом деле работают вычисления с плавающей запятой. К счастью, их можно объяснить иначе. Воспринимайте экспоненту как окно (Window) или интервал между двумя соседними целыми степенями двойки. Мантиссу воспринимайте как смещение (Offset) в этом окне.


Три части числа с плавающей запятой.

Окно сообщает нам, между какими двумя последовательными степенями двойки будет число: [0,1], [1,2], [2,4], [4,8] и так далее (вплоть до [,]. Смещение разделяет окно на сегментов. С помощью окна и смещения можно аппроксимировать число. Окно — это отличный механизм защиты от выхода за границы. Достигнув максимума в окне (например, в [2,4]), можно «переплыть» вправо и представить число в пределах следующего окна (например, [4,8]). Ценой этого будет только небольшое снижение точности, потому что окно становится в два раза больше.

Викторина: сколько точности теряется, когда окно закрывает больший интервал? Давайте возьмём пример с окном [0,1], в котором 8388608 смещений накладываются на интервал размером 1, что даёт нам точность . В окне [2048,4096] 8388608 смещений накладываются на интервал , что даёт нам точность .

На рисунке ниже показано, как кодируется число 6,1. Окно должно начинаться с 4 и заканчиваться следующей степенью двойки, т.е. 8. Смещение находится примерно посередине окна.


Значение 6,1 аппроксимированное с помощью числа с плавающей запятой.

Давайте возьмём ещё один пример с подробным вычислением представлением в виде числа с плавающей точкой хорошо известного всем нам значения: 3,14.

В двоичном виде это преобразуется в следующее:

  • S = 0 = 0b
  • E = 128 = 10000000b
  • M = 4781507 = 10010001111010111000011b


Двоичное представление с плавающей точкой числа 3,14.

То есть значение 3,14 аппроксимируется как 3,1400001049041748046875.

Соответствующее значение в непонятной формуле:

И, наконец, графическое представление с окном и смещением:


Окно и смещение числа 3,14.

Интересный факт: если модули операций с плавающей запятой были такими медленными, почему в языке C в результате использовали типы float и double? Ведь в машине, на которой изобретался язык (PDP-11), не было модуля операций с плавающей запятой! Дело в том, что производитель (DEC) пообещал Деннису Ритчи и Кену Томпсону, что в следующей модели он будет. Они были любителями астрономии и решили добавить в язык эти два типа.

Интересный факт: те, кому в 1991 году действительно нужен был аппаратный модуль операций с плавающей запятой, могли его купить. Единственными, кому он мог понадобиться в то время, были учёные (по крайней мере, так Intel понимала потребности рынка). На рынке они позиционировались как «математические сопроцессоры». Их производительность была средней, а цена огромной (200 долларов 1993 года — это 350 долларов в 2016 году.). В результате уровень продаж оказался посредственным.

Надеюсь, статья была вам полезна!

Число с плавающей точкой

Содержание:

Изображение: http://pikabu.ru/

Вступление

В первые же дни изучения Java я наткнулся на такой любопытный вид примитивов, как числа с плавающей точкой. Меня сразу заинтересовали их особенности и, тем более, способ записи в двоичном коде (что взаимосвязано). В отличие от какого-либо диапазона целых чисел, даже в очень малом промежутке (например от 1 до 2) их бесконечное множество. И имея конечный размер памяти, невозможно выразить это множество. Так как же они выражены в двоичном коде и как работают? Увы, объяснения в вики и достаточно клёвой статьи на хабре тут не дали мне полного понимания, хотя заложили базу. Осознание пришло лишь после этой статьи-разбора наутро после прочтения.

Экскурс в историю

(почерпнул из этой статьи на Хабре) В 60-70 гг, когда компьютеры были большими, а программы — маленькими, ещё не было единого стандарта вычислений, как и стандарта выражения самого числа с плавающей точкой. Каждый компьютер делал это по-своему, и ошибки были у каждого свои. Но в середине 70-х компания Intel решила сделать новые процессоры с поддерживаемой "улучшенной" арифметикой и заодно стандартизировать её. Для разработки привлекли профессоров Уильяма Кэхэна и Джона Палмера (нет, не автора книг про пиво). Не обошлось без драм, но всё же новый стандарт был разработан. Сейчас этот стандарт называют IEEE754

Формат записи числа с плавающей точкой

Ещё в учебниках школьного курса все сталкивались с непривычным способом записи очень больших или очень малых чисел вида 1,2×103 или 1,2E3, что равно 1,2×1000 = 1200. Это называется способ записи через экспоненту. В данном случае мы имеем дело с выражением числа по формуле: N=M×np, где
  • N = 1200 — получаемое число
  • M = 1,2 — мантисса — дробная часть, без учёта порядков
  • n = 10 — основание порядка. В данном случае и когда речь не идёт о компьютерах, основанием выступает цифра 10
  • p = 3 — степень основания
Довольно часто основание порядка подразумевается, как 10 и записывают лишь мантиссу и значение степени основания, разделяя их буквой E. В нашем примере я привёл равнозначные записи 1,2×103 и 1,2E3
Если всё понятно, и ностальгический экскурс в школьную программу мы закончили, то сейчас рекомендую забыть это, т. к. при формировании числа с плавающей точкой мы имеем дело со степенями двойки, а не десятки, т.е. n = 2, вся стройная формула 1,2E3 ломается и это здорово сломало мне мозг.

Знак и степень

И что мы имеем? В итоге мы также имеем двоичное число, которое состоит из мантиссы — часть, которую будем возводить в степень и саму степень. Кроме этого, так же как принято и у целочисленных типов, в числах с плавающей точкой есть бит, который определяет знак — будет число положительным или отрицательным. В качестве примера предлагаю рассмотреть тип float, который состоит из 32 бит. С числами двойной точности double логика такая же, только в два раза больше бит. Из 32 бит, первый старший отводится на знак, следующие 8 бит отводятся на экспоненту — степень, на которую будем возводить мантиссу, а остальные 23 бита — на мантиссу. Для демонстрации давайте посмотрим на пример пример: С первым битом всё очень просто. Если значение первого бита 0, то число, которое мы получим будет
положительным
. Если бит равен 1, то число будет отрицательным. Следующий блок из 8 бит — блок с экспонентой. Экспонента записывается как обычное восьмибитное число, а чтоб получить требуемую степень нам нужно из полученного числа вычесть 127 В нашем случае восемь бит экспоненты — это 10000001. Это соответствует числу 129. Если есть вопрос, как это посчитать, то на картинке быстрый ответ. Развёрнутый можно получить на любом курсе булевой алгебры. 1×27 + 0×26 + 0×25 + 0×24 + 0×23 + 0×22 + 0×21 + 1×20 = 1×128 + 1×1 = 128+1=129 Не сложно посчитать, что максимальное число, которое мы можем получить из этих 8 бит 111111112 = 25510 (подстрочные 2 и 10 означают двоичную и десятеричную системы исчисления) Однако, если использовать только положительные значения степени (от 0 и до 255), то полученные числа будут иметь много чисел перед запятой, но не после? Чтоб получать отрицательные значения степени, из сформированной экспоненты нужно вычитать
127
. Таким образом, диапазон степеней будет от -127 до 128. Если использовать наш пример, то нужная степень будет 129-127 = 2. Пока запоминаем это число.

Мантисса

Теперь о мантиссе. Она состоит из 23 бит, однако в начале всегда подразумевается ещё одна единица, на которую биты не выделяются. Это сделано в целях целесообразности и экономии. Одно и то же число можно выражать разными степенями, добавляя к мантиссе нули перед или после запятой. Проще всего это понять с десятичной экспонентой: 120 000 = 1,2×105 = 0,12×106 = 0,012×107 = 0,0012×108 и т.д. Однако, введя фиксированное число в голове мантиссы мы каждый раз будем получать новые числа. Примем как данность, что перед нашими 23 битами будет ещё один с единицей. Обычно этот бит от остальных отделают точкой, которая, впрочем, ничего не значит. Просто так удобнее 1 . 11100000000000000000000 Теперь полученную мантиссу нужно возводить в степень слева направо, уменьшая с каждым шагом степень на одну. Стартуем со значения степени, который мы получили в результате вычисления, т. е.
2
(Я специально выбрал простой пример, чтоб не писать каждое значение степени двойки и в приведенной таблице не вычислял их, когда соответствующий бит равен нулю) 1×22 + 1×21 + 1×20 + 1×2-1 = 1×4 + 1×2 + 1×1 + 1×0,5 = 4+2+1+0,5 = 7,5 и получили результат 7,5, правильность можно проверить, например, по этой ссылке

Итоги

Стандартное число с плавающей точкой типа float состоит из 32 бит, первый бит — знак (+ или -), следующие восемь — экспонента, следующие 23 — мантисса По знаку — если бит 0 — число положительное. Если бит 1 — отрицательное. По экспоненте — побитно переводим в десятичное число (первый слева бит — 128, второй — 64, третий — 32, четвёртый — 16, пятый — 8, шестой — 4, седьмой — 2, восьмой — 1), из полученного числа вычитаем 127, получаем степень с которой будем стартовать. По мантиссе — к имеющимся 23 битам спереди дописываем ещё один бит со значением 1 и с него начинаем возводить в полученную нами степень, с каждым следующим битом декрементируя эту степень. That's all folks, kids!
P. S.: В виде домашнего задания, используя эту статью, оставьте в комментариях свои версии, почему при большом количестве арифметических операций с числами с плавающей точкой возникают ошибки точности

Блок операций с плавающей точкой

Компания Weitek также выпускала математические сопроцессоры для платформ 68000 и

Устройство FPU

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

Внутри FPU числа хранятся в 80-битном формате с плавающей запятой, для записи же или чтения из памяти могут использоваться:

  • один из трёх форматов с плавающей точкой (32, 64 и 80 бит),
  • целочисленные форматы (16, 32 и 64 бита),
  • 80-битный BCD-формат.

Поддерживаемые математические операции: арифметические операции, сравнение, деление по модулю, округление, смена знака, модуль, квадратный корень, синус, косинус, частичный тангенс, частичный арктангенс, загрузка константы (0, 1, число пи, log2(10), log2(e), lg(2), ln(2)) и некоторые другие специфические операции.

FPU умеет обрабатывать пограничные состояния с помощью специальных значений, представимых форматом с плавающей запятой:

  • денормализованное число (число, близкое к переполнению; при дальнейшем возрастании модуля денормализованное число становится бесконечностью),
  • бесконечность (положительная и отрицательная), возникает при делении на нуль ненулевого значения а также при переполнениях,
  • англ. not-a-number (NaN)). Нечисла могут определять такие случаи, как:
    • неопределённость (IND), возникает при комплексном результате (например, при вычислении квадратного корня из отрицательного числа) и в некоторых других случаях,
    • недействительное значение (qNaN, sNaN) - может использоваться компилятором (для предотвращения использования неинициализированных переменных) или отладчиком,
  • нуль - в формате с плавающей запятой, нуль также считается специальным значением.

В зависимости от флагов FPU, специальные значения могут инициировать обработку исключения операционной системой.

См. также

Обзор архитектуры процессоров SHARC | Analog Devices

32-разрядные процессоры с плавающей точкой SHARC® компании Analog Devices основаны на расширенной гардвардской (супергарвардской) архитектуре, которая обеспечивает сочетание исключительной производительности ядра и памяти с превосходной пропускной способностью ввода/вывода. В супергарвардской архитектуре оригинальная концепция раздельных шин памяти программ и памяти данных расширена за счет добавления процессора ввода/вывода с отдельными шинами. Помимо архитектурных решений, призванных удовлетворить потребности самых ресурсоемких задач обработки сигналов в режиме реального времени, в процессорах SHARC интегрированы блоки памяти большого объема и различные специализированные периферийные модули, предназначенные для упрощения процесса проектирования и сокращения времени от задумки концепции до выхода продукта на рынок.

На сегодняшний день линейка процессоров SHARC включает в себя четыре поколения программно совместимых продуктов, варьирующихся от компонентов начального уровня стоимостью менее 10$ до компонентов с наивысшим быстродействием, которые обеспечивают производительность арифметических операций в форматах с фиксированной и плавающей точкой до 450 МГц/2700 MFLOPs (миллионов операций с плавающей точкой в секунду). Независимо от выбранного продукта все процессоры семейства SHARC обладают общим набором особенностей и функциональных возможностей, которые могут представлять интерес во многих отраслях электроники и задачах цифровой обработки сигналов. Эта унификация функциональных возможностей позволяет пользователям процессоров SHARC использовать существующее программное обеспечение и накопленный опыт при переходе к продуктам семейства с большей производительностью и большей степенью интеграции.

Общие архитектурные особенности

  • Арифметика с 32/40-разрядными числами в формате с плавающей точкой стандарта IEEE
  • 32-разрядные умножители чисел в формате с фиксированной точкой с 64-разрядным произведением и 80-разрядным накоплением
  • Отсутствие арифметического конвейера; все вычисления выполняются за один такт
  • Аппаратная поддержка адресации циклических буферов
  • 32 указателя адреса для поддержки 32 циклических буферов
  • Аппаратная поддержка до шести вложенных циклов с нулевыми непроизводительными издержками
  • Алгебраический синтаксис языка ассемблера с богатым набором операций
  • Набор команд с поддержкой условных арифметических операций, манипуляции битами, деления и взятия квадратного корня, а также извлечения и внесения битовых полей
  • Контроллер прямого доступа к памяти (DMA) для фоновых пересылок данных с нулевыми непроизводительными издержками, осуществляемых на максимальной рабочей частоте без вмешательства ядра процессора

Продукты первого поколения семейства SHARC обладают производительностью до 66 МГц/ 198 MFLOPs и образуют фундамент семейства процессоров SHARC. Их простой в применении набор команд, поддерживающий 32-разрядные данные в формате с фиксированной точкой и 32/40-разрядные в формате с плавающей точкой, в комбинации с большим объемом памяти и продвинутыми портами связи позволяют использовать данные процессоры в широком спектре задач, требующих параллельных вычислений, в таких областях, как бытовая аудиоаппаратура, медицинские системы визуальной диагностики, военная электроника, промышленная и измерительная техника.

Продукты второго поколения семейства SHARC дают повышение производительности в задачах обработки сигналов в два раза (100 МГц / 600 MFLOPs) за счет поддержки режима SIMD (Single-Instruction, Multiple-Data, одна команда-много данных). Благодаря расширению аппаратных средств количество вычислительных ресурсов, доступных для системного программиста, удваивается по сравнению с процессорами SHARC первого поколения. Продукты второго поколения содержат два набора умножителей, АЛУ, устройств сдвига и регистровых файлов данных, что приводит к значительному увеличению общей производительности системы в разнообразных задачах. Особый интерес это может представлять для бытовых, автомобильных и профессиональных аудиосистем, в которых режим SIMD обеспечивает эффективное выполнение алгоритмов, связанных с обработкой стереосигналов.

Продукты третьего поколения семейства SHARC основаны на усовершенствованной архитектуре SIMD, которая позволяет увеличить производительность процессорного ядра до 450 МГц/2700 MFLOPs. В них также интегрированы разнообразные конфигурации постоянной памяти (ROM) и специализированные периферийные модули для аудиосистем, обеспечивающие сокращение времени от задумки концепции до выпуска продукта на рынок и сократить общую стоимость компонентов системы. Повышенный уровень производительности и интеграции периферийных модулей позволяет рассматривать процессоры SHARC третьего поколения в качестве однокристальных решений для разнообразных приложений обработки звука.

Четвертое поколение процессоров SHARC® на сегодняшний день включает в себя ADSP-21486, ADSP-21487, ADSP-21488 и ADSP-21489. Эти процессоры обладают повышенной производительностью, имеют аппаратные ускорители операций фильтрации, прикладные периферийные модули и периферийные модули для аудиосистем, а также новые конфигурации памяти с поддержкой новейших алгоритмов декодирования объемного звука. Все устройства совместимы друг с другом по выводам и обладают полной программной совместимостью со всеми предыдущими процессорами SHARC. Эти новые представители четвертого поколения семейства процессоров SHARC построены на базе ядра, работающего в режиме SIMD с поддержкой арифметических операций над 32-разрядными числами в формате с фиксированной точкой и 32-/40-разрядными числами в формате с плавающей точкой, что делает их особенно привлекательными для высококачественных систем обработки звука.


Дополнительные ресурсы

Руководство новичка по цифровой обработке сигналов (DSP)


Числа с плавающей точкой    . Язык Си

Читайте также

Нельзя просто использовать вычисления с плавающей точкой

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

21. Превратное обратное, или Ошибки при работе с плавающей точкой

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

R.2.5.3 Константы с плавающей точкой

R.2.5.3 Константы с плавающей точкой Константы с плавающей точкой состоят из целой части, символа точка, дробной части, e или E, целого показателя с возможным знаком и возможным окончанием, указывающим тип. Целая и дробная части состоят из последовательности десятичных

R.4.3 Значения с плавающей точкой и двойной точностью

R.4.3 Значения с плавающей точкой и двойной точностью Для выражений типа float может использоваться арифметика с обычной точностью. Если значение с плавающей точкой меньшей точности преобразуется в значение типа float равной или большей точности, то изменения значения не

R.4.4 Целочисленные и числа с плавающей точкой

R.4.4 Целочисленные и числа с плавающей точкой Преобразование значения с плавающей точкой к целочисленному типу сводится к "усечению", т.е. отбрасыванию дробной части. Такие преобразования зависят от машины, в частности в какую сторону будет проходить усечение для

5.3. Округление чисел с плавающей точкой

5.3. Округление чисел с плавающей точкой Кирк: Какие, вы говорите, у нас шансы выбраться отсюда? Спок: Трудно сказать точно, капитан. Приблизительно 7824.7 к одному. Стар Трек, «Миссия милосердия» Метод round округляет число с плавающей точкой до целого:pi = 3.14159new_pi = pi.round  # 3temp =

5.4. Сравнение чисел с плавающей точкой

5.4. Сравнение чисел с плавающей точкой Печально, но факт: в компьютере числа с плавающей точкой представляются неточно. В идеальном мире следующий код напечатал бы «да», но на всех машинах где мы его запускали, печатается «нет»:x = 1000001.0/0.003y = 0.003*xif y == 1000001.0 puts "да"else puts

3.4. Сравнение чисел с плавающей точкой с ограниченной точностью

3.4. Сравнение чисел с плавающей точкой с ограниченной точностью ПроблемаТребуется сравнить значения с плавающей точкой, но при этом выполнить сравнение на равенство, больше чем или меньше чем с ограниченным количеством десятичных знаков. Например, требуется, чтобы 3.33333 и

Описание переменных с плавающей точкой

Описание переменных с плавающей точкой      Переменные с плавающей точкой описываются и инициализируются точно таким же образом, что и переменные целого типа. Ниже приведено несколько примеров: float noah, jonah;double trouble;float planck = 6.63e-

Константы с плавающей точкой   

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

Двоичные числа с плавающей точкой

Двоичные числа с плавающей точкой  Числа с плавающей точкой хранятся в памяти в виде двух частей: двоичной дроби и двоичного порядка. Посмотрим, как это делается. Двоичные дроби Обычную дробь .324 можно представить в виде3/10 + 2/100 + 4/1000,где знаменатели - увеличивающиеся

Константы с плавающей точкой

Константы с плавающей точкой Константа с плавающей точкой — это действительное десятичное положительное число. Оно включает целую часть, дробную часть и экспоненту. Константы с плавающей точкой имеют следующий формат

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

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

2.4.2 Константы с Плавающей Точкой

2.4.2 Константы с Плавающей Точкой Константы с плавающей точкой имеют тип double. Как и в предыдущем случае, компилятор должен предупреждать о константах с плавающей точкой, которые слишком велики, чтобы их моно было представить. Вот некоторые константы с плавающей точкой:1.23

2.4.4 Константы с Плавающей Точкой

2.4.4 Константы с Плавающей Точкой Константа с плавающей точкой состоит из целой части, десятичной точки, мантиссы, е или Е и целого показателя стпени (возможно, но не обязательно, со знаком). Целая часть и мантисса обе состоят из последовательности цифр. Целая часть или

>> (Bitwise Right Shift) operator—ArcGIS Pro

Доступно с лицензией Spatial Analyst.

Доступно с лицензией Image Analyst.

Обсуждение

При использовании оператора с растровым входом результат будет растром. Но если все входные значения — числа, результат будет числом.

Если в выражении используется несколько операторов, они не обязательно выполняются слева направо. Оператор с высшим значением приоритета будет выполнен первым. Более подробно см. в таблице приоритета операторов в разделе Работа с операторами в Алгебре карт. Порядок выполнения можно изменить с помощью скобок.

Побитовые операторы работают с 32-разрядными целыми числами.

При вводе значений с плавающей запятой они конвертируются в целочисленные значения посредством сокращения знаков перед выполнением битовой операции. Выходные значения всегда целочисленные.

Для выполнения битовой операции требуется ввести два исходных значения (растры или числа).

При выполнении операции побитового сдвига вправо имеет значение порядок ввода.

Бинарные значения хранятся в виде поразрядного дополнения до двух.

Самая левая битовая позиция зарезервирована для знака значения (положительное или отрицательное). Если целое число положительное, бит имеет значение 0, а если отрицательное – бит имеет значение 1.

Побитовая операция сдвига вправо не выполняет свертывания бит. Крайний правый бит отбрасывается.

Также операцию побитового сдвига влево можно выполнить как a >>= b, что является альтернативным способом написания a = a >> b.

Если оба входных растра одноканальные либо входные данные - одноканальный растр и константа, выходной растр будет одноканальным.

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

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

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

Если в обоих входных наборах данных есть одна переменная, но разные названия, задайте переменную геообработки matchMultidimensionalVariable как False, чтобы выполнить операцию.

Если один из входных данных является многомерным растром, а другой входной параметр является константой, оператор выполнит операцию для всех срезов для всех переменных с постоянным значением, и на выходе будет многомерный растр.

Не удается найти страницу | Autodesk Knowledge Network

(* {{l10n_strings.REQUIRED_FIELD}})

{{l10n_strings.CREATE_NEW_COLLECTION}}*

{{l10n_strings.ADD_COLLECTION_DESCRIPTION}}

{{l10n_strings.COLLECTION_DESCRIPTION}} {{addToCollection.description.length}}/500 {{l10n_strings.TAGS}} {{$item}} {{l10n_strings.PRODUCTS}} {{l10n_strings.DRAG_TEXT}}  

{{l10n_strings.DRAG_TEXT_HELP}}

{{l10n_strings.LANGUAGE}} {{$select.selected.display}}

{{article.content_lang.display}}

{{l10n_strings.AUTHOR}}  

{{l10n_strings.AUTHOR_TOOLTIP_TEXT}}

{{$select.selected.display}} {{l10n_strings.CREATE_AND_ADD_TO_COLLECTION_MODAL_BUTTON}} {{l10n_strings.CREATE_A_COLLECTION_ERROR}}

Операции с плавающей запятой - обзор

1.2.3 Влияние компьютерных архитектур

Снова и снова появляются выпуски новостей для суперкомпьютеров с наибольшим числом операций с плавающей запятой в секунду. При экстраполяции этой стратегии на суперкомпьютеры можно довести ее до крайности. В действительности было предложено целых триллион плюс (1,6 триллиона) менее дорогих микросхем, организованных в конвейерном / параллельном режиме или конфигурации для суперкомпьютеров. Это кажется логичным выбором для бизнеса.Новый суперкомпьютер IBM (Sequoia периодов 2011–2012 годов) использует 1,6 триллиона процессоров и 1,6 петабайта памяти. Он использует технологию IBM Blue Gene (скорость 500 терафлопс, т. Е. 500 триллионов флоп) / с предлагает расчетных 20 петафлопс (т. Е. 20 000 триллионов флоп) / с вычислительной мощности. Однако реализованная скорость составила 16,3248 Петафлопс / с. Энергоэффективность также высока, предлагая 3050 вычислений на каждый ватт мощности. Инфраструктура использует передовую оптоволоконную коммутацию для межузловой передачи данных.Примеры использования таких суперкомпьютеров - в астрономии, исследованиях генома человека и энергии. Sequoia, построенная в Ливерморской лаборатории Лоуренса Министерства энергетики, работает с 2012 года. В ней используются различные варианты операционной системы Linux. Мы приводим трех основных претендентов (по состоянию на ноябрь 2012 г.) и их характеристики только для сравнения.

Titan, система Cray XK7, установленная в Ок-Ридже, система 2,2 ГГц (OLCF) достигла 17,59 Петафлоп / с (квадриллионы вычислений в секунду) в тесте Linpack.Titan имеет 560 640 процессоров, в том числе 261 632 ядра ускорителя NVIDIA K20x. Потребляемая мощность составляет 8,21 МВт (10 6 Вт), а объем памяти (71,0144 × 10 4 ) ГБ. Он работает с операционной системой Cray Linux и межсоединением Cray-Gemini.

Система IBM Sequoia – BlueGene / Q, Power BQC 16C, 1,60 ГГц, Custom в Ливерморской национальной лаборатории (Ливерморская национальная лаборатория), система 1,60 ГГц достигла скорости 16,3248 Петафлопс / с. Sequoia имеет 1572864 процессорных ядра и потребляет 7.890 МВт мощности. Размер памяти составляет (157,2864 × 10 4 ) ГБ и работает с операционной системой Linux и настраиваемым межсоединением.

Система Fujitsu K Computer, SPARC64 VIllfx, 2,0 ГГц, расположенная в RIKEN Advanced Institute for Computational Science (AICS) в Кобе, Япония (Riken Advanced Institute of Computational Science), достигла 10,510 Петафлопс / с в тесте Linpack. K Computer имеет 705 024 процессора. Потребляемая мощность составляет 12,57 МВт, объем памяти (141.0048 × 10 4 ) ГБ. Он работает с операционной системой Cray Linux и настраиваемым межсоединением (Tofu).

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

Точность и операции с плавающей запятой

Точность и операции с плавающей запятой

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

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

Примечание: Точность чисел с одинарной и двойной точностью в IDL зависит как от платформы, так и от компилятора. Поскольку IDL написан на C, числа в IDL будут вести себя идентично программе, написанной на C на вашей платформе.Для получения подробной информации о компиляторе и флагах компиляции для вашей платформы вы можете изучить системную переменную! MAKE_DLL.

Чтобы понять, почему числа с плавающей запятой по своей природе неточны, рассмотрим следующее:

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

Другими словами, значения с плавающей запятой являются приближениями конечной точности бесконечно точных чисел.

Например, некоторые числа точно могут быть представлены числами с плавающей запятой одинарной точности:

 ПЕЧАТЬ, 2.0, ФОРМАТ = '(f25.16)' 
 ПЕЧАТЬ, 2.0 EQ 2.0d? 'истина': 'ложь' 
 

IDL отображает:

 2.0000000000000000 
 правда 

Другие числа не представимы точно:

 ПЕЧАТЬ, 0.1, FORMAT = '(f25.16)' 
 ПЕЧАТЬ, 0.1 EQ 0.1d? 'истина': 'ложь' 
 

IDL отображает:

 0,10000000141 
 ложь 
 

Из-за этих различий при использовании многих математических подпрограмм IDL обратите внимание, что их вызов с числами с плавающей запятой одинарной или двойной точности может дать несколько разные результаты.

Дополнительные сведения о числах с плавающей запятой см. В стандарте IEEE для арифметики с плавающей запятой (IEEE 754), кратко изложенном в Wikipedia.орг.

Ошибка округления


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

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

Ошибки округления суммируются.В зависимости от используемого алгоритма расчет с использованием арифметических операций n может иметь общую ошибку округления от SQRT ( n ), умноженную на машинную точность, до n , умноженную на машинную точность.

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

Ошибка усечения


Другой тип ошибки также присутствует в некоторых численных алгоритмах.Ошибка усечения - это ошибка, вносимая процессом численного приближения непрерывной функции путем ее вычисления в конечном числе дискретных точек. Часто точность может быть увеличена (опять же за счет некоторой стоимости времени вычислений) путем увеличения количества оцениваемых дискретных точек.

Например, рассмотрим процесс вычисления

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

Несколько подпрограмм IDL позволяют указать значения отсечения в таких случаях (см., Например, INT_2D. При написании собственных подпрограмм на IDL важно учитывать этот компромисс между точностью и временем вычислений.

Подпрограммы для математической оценки ошибок


Ниже приводится краткое описание подпрограмм IDL для проверки состояния математических ошибок и характеристик машины.

Процедура

Описание

CHECK_MATH

Возвращает и очищает состояние накопленных математических ошибок.

КОНЕЧНЫЙ

Возвращает True, если его аргумент конечен.

МАЧАР

Определяет и возвращает зависящие от машины параметры, влияющие на арифметику с плавающей запятой.

Точность и операции с плавающей запятой Справочные документы

Бёрден, Ричард Л., Дж. Дуглас Фейрес и Альберт К. Рейнольдс. Численный анализ . Бостон: PWS Publishing, 1993. ISBN 0-534-93219-3

Гольдберг, Дэвид. «Что должен знать каждый компьютерный ученый об арифметике с плавающей запятой» в Computing Surveys , март 1991 г. Association for Computing Machinery, Inc.

Stoer, J., and R. Bulirsch. Введение в численный анализ . Нью-Йорк: Springer-Verlag, 1980. ISBN 0-387--4

Press, William H. et al. Числовые рецепты на языке C: Искусство научных вычислений . Кембридж: Издательство Кембриджского университета, 1992. ISBN 0-521-43108-5

Проблемы и ограничения

- документация Python 3.9.6

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

имеет значение 1/10 + 2/100 + 5/1000, и точно так же двоичная дробь

имеет значение 0/2 + 0/4 + 1/8. Эти две фракции имеют одинаковые значения, единственное реальная разница в том, что первая записана в десятичной дробной системе счисления, а второй по базе 2.

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

Задачу сначала легче понять по основанию 10. Рассмотрим дробь. 1/3. Вы можете аппроксимировать это как дробь по основанию 10:

или лучше

или лучше

и так далее. Независимо от того, сколько цифр вы хотите записать, результат никогда не будет точно 1/3, но будет все более точным приближением 1/3.

Таким же образом, независимо от того, сколько цифр по основанию 2 вы хотите использовать, десятичное значение 0,1 не может быть представлено точно как дробь с основанием 2.В базе 2, 1/10 - бесконечно повторяющаяся дробь

 0,0001100110011001100110011001100110011001100110011 ...
 

Остановитесь на любом конечном числе битов, и вы получите приближение. На большинстве Сегодняшние машины с плавающей запятой аппроксимируются двоичной дробью с числитель, использующий первые 53 бита, начиная со старшего разряда и со знаменателем в виде степени двойки. В случае 1/10 двоичная дробь 3602879701896397/2 ** 55 , что близко, но не совсем равно истинному значению 1/10.

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

 >>> 0,1
0,1000000000000000055511151231257827021181583404541015625
 

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

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

Интересно, что существует много разных десятичных чисел, которые имеют одно и то же ближайшая приближенная двоичная дробь. Например, числа 0,1 и 0,10000000000000001 и 0.1000000000000000055511151231257827021181583404541015625 все приблизительно 3602879701896397/2 ** 55 . Поскольку все эти десятичные значения имеют одинаковое приближение, может отображаться любое из них с сохранением инварианта eval (repr (x)) == x .

Исторически подсказка Python и встроенная функция repr () выбирали тот, у которого 17 значащих цифр, 0,10000000000000001 . Начиная с Python 3.1, Python (в большинстве систем) теперь может выбирать самый короткий из они и просто отображают 0,1 .

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

Для более приятного вывода вы можете использовать форматирование строки для получения ограниченного числа значащих цифр:

 >>> format (math.pi, '.12g') # вывести 12 значащих цифр
"3.14159265359"

>>> format (math.pi, '.2f') # ставим 2 цифры после точки
«3,14»

>>> repr (math.pi)
"3,141592653589793"
 

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

Одна иллюзия может породить другую. Например, поскольку 0,1 - это не точно 1/10, суммирование трех значений 0,1 также может не дать точно 0,3:

 >>> .1 + .1 + .1 == .3
Ложь
 

Кроме того, поскольку 0,1 не может приблизиться к точному значению 1/10 и 0,3 не может приблизиться к точному значению 3/10, затем округление с round () функция не может помочь:

 >>> раунд (.1, 1) + раунд (.1, 1) + раунд (.1, 1) == раунд (.3, 1)
Ложь
 

Хотя числа не могут быть приближены к их предполагаемым точным значениям, функция round () может быть полезна для последующего округления, чтобы результаты при неточных значениях становятся сопоставимыми между собой:

 >>> круглый (.1 + .1 + .1, 10) == раунд (.3, 10)
Правда
 

Двоичная арифметика с плавающей запятой преподносит много подобных сюрпризов. Эта проблема с «0,1» подробно разъясняется ниже в разделе «Ошибка представления» раздел. См. Опасности, связанные с плавающей точкой для более полного описания других общих сюрпризов.

Как говорится в конце, «нет простых ответов». Тем не менее, не следует необоснованно остерегайтесь чисел с плавающей запятой! Ошибки в операциях Python с плавающей запятой наследуются от оборудования с плавающей запятой, и на большинстве машин порядка более 1 части из 2 ** 53 за операцию.Этого более чем достаточно для большинства задач, но помните, что это не десятичная арифметика и что каждая операция с плавающей запятой может иметь новую ошибку округления.

Хотя патологические случаи действительно существуют, для наиболее случайного использования чисел с плавающей запятой арифметических расчетов, вы увидите ожидаемый результат, если просто округлите отображение ваших окончательных результатов с количеством десятичных цифр, которое вы ожидаете. str () обычно достаточно, а для более точного управления см. str.format () спецификаторы формата метода в синтаксисе строки формата.

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

Другая форма точной арифметики поддерживается модулем дробей который реализует арифметику на основе рациональных чисел (поэтому числа вроде 1/3 можно представить точно).

Если вы интенсивно используете операции с плавающей запятой, вам следует взглянуть на в пакете Numerical Python и многих других пакетах для математических и статистические операции, предоставляемые проектом SciPy.См. .

Python предоставляет инструменты, которые могут помочь в тех редких случаях, когда вы действительно - хотят знать точное значение числа с плавающей запятой. В float.as_integer_ratio () метод выражает значение float как фракция:

 >>> х = 3,14159
>>> x.as_integer_ratio ()
(3537115888337719, 11258992624)
 

Так как соотношение точное, его можно использовать для воссоздания без потерь первоначальная стоимость:

 >>> х == 3537115888337719/11258992624
Правда
 

Поплавок .Метод hex () выражает число с плавающей запятой в шестнадцатеричном формате (с основанием 16), снова давая точное значение, сохраненное на вашем компьютере:

 >>> x.hex ()
'0x1.921f9f01b866ep + 1'
 

Это точное шестнадцатеричное представление может быть использовано для восстановления точное значение с плавающей запятой:

 >>> x == float.fromhex ('0x1.921f9f01b866ep + 1')
Правда
 

Поскольку представление точное, это полезно для надежного переноса значений через разные версии Python (независимость от платформы) и обмен данные на других языках, поддерживающих тот же формат (например, Java и C99).

Еще одним полезным инструментом является функция math.fsum () , которая помогает уменьшить потеря точности при суммировании. Он отслеживает «потерянные цифры», поскольку значения добавлен к промежуточной сумме. Это может повлиять на общую точность так что ошибки не накапливаются до точки, где они влияют на итоговая сумма:

 >>> сумма ([0,1] * 10) == 1,0
Ложь
>>> math.fsum ([0.1] * 10) == 1.0
Правда
 

15,1. Ошибка представления

В этом разделе объясняется «0.1 ”подробно и показывает, как вы можете точный разбор подобных случаев самостоятельно. Базовое знакомство с двоичным кодом предполагается представление с плавающей запятой.

Ошибка представления относится к тому факту, что некоторые (на самом деле большинство) десятичные дроби не могут быть представлены точно как двоичные дроби (с основанием 2). Это основная причина, по которой Python (или Perl, C, C ++, Java, Fortran и многие другие другие) часто не отображает точное десятичное число, которое вы ожидаете.

Почему? 1/10 нельзя точно представить в виде двоичной дроби.Почти все машины сегодня (ноябрь 2000 г.) используют арифметику с плавающей запятой IEEE-754, и почти все платформы отображают Python с плавающей запятой на «двойную точность» IEEE-754. 754 double содержат 53 бита точности, поэтому при вводе компьютер стремится преобразовать 0,1 в ближайшую дробь, которая может иметь вид J /2 ** N , где J - целое число, содержащее ровно 53 бита. Переписывание

как

и вспоминая, что J имеет ровно 53 бита (это > = 2 ** 52 , но <2 ** 53 ), лучшее значение для N - 56:

 >>> 2 ** 52 <= 2 ** 56 // 10 <2 ** 53
Правда
 

То есть 56 - единственное значение для N , которое оставляет J ровно с 53 битами.В наилучшее возможное значение для Дж. - это округленное частное:

.
 >>> q, r = divmod (2 ** 56, 10)
>>> г
6
 

Так как остаток больше половины от 10, получается наилучшее приближение путем округления:

Следовательно, наилучшее возможное приближение к 1/10 с двойной точностью 754:

 7205759403792794/2 ** 56
 

Если разделить числитель и знаменатель на два, то получится:

 3602879701896397/2 ** 55
 

Обратите внимание, что, поскольку мы округлили в большую сторону, это на самом деле немного больше 1/10; если бы мы не округлили, частное было бы немного меньше, чем 1/10.Но ни в коем случае не может быть ровно 1/10!

Итак, компьютер никогда не «видит» 1/10: то, что он видит, является точной приведенной дробью. выше, наилучшее 754 двойное приближение, которое оно может получить:

 >>> 0,1 * 2 ** 55
3602879701896397.0
 

Если мы умножим эту дробь на 10 ** 55, мы сможем увидеть значение, равное 55 десятичных цифр:

 >>> 3602879701896397 * 10 ** 55 // 2 ** 55
1000000000000000055511151231257827021181583404541015625
 

означает, что точное число, хранящееся в компьютере, равно десятичное значение 0.1000000000000000055511151231257827021181583404541015625. Вместо отображения полного десятичного значения многие языки (включая более старые версии Python), округлите результат до 17 значащих цифр:

 >>> формат (0.1, '.17f')
'0.10000000000000001'
 

Модули , дроби, и , десятичные, , производят эти вычисления. легкий:

 >>> из десятичного числа Импорт Десятичный
>>> из импорта дробей Дробь

>>> Fraction.from_float (0.1)
Дробь (3602879701896397, 36028797018963968)

>>> (0.1) .as_integer_ratio ()
(3602879701896397, 36028797018963968)

>>> Десятичный.from_float (0.1)
Десятичный ('0,1000000000000000055511151231257827021181583404541015625')

>>> формат (Decimal.from_float (0.1), '.17')
'0.10000000000000001'
 

Модуль 4 Раздел 3 - Операции с плавающей запятой

Как складывать числа с плавающей запятой? Вычесть их? Чтобы ответить на это вопрос, сначала изучите, как вы добавляете следующие десятичные числа: 34.568 + 0,0072. Первое, что нужно сделать, это записать числа в столбец, выравнивая десятичную точку, затем выполните то, что составляет целое число кроме того, сохраняя десятичную точку в фиксированном положении.

А как насчет чисел, записанных в экспоненциальной форме? Например, как бы вы прибавили 4,56 x 10 3 к 53,21 x 10 -1 ? Бы эта работа точно так же?

Ну, не совсем так. Помните, что показатель степени означает, что точка счисления на самом деле принадлежит к другому положению, чем то, в котором он показан.Для Например, в 4,56 x 10 3 показатель степени «3» означает десятичную точку действительно принадлежит на три места правее того места, где он находится, так что это число (написанное без показателей) - 4560. Итак, выравнивая десятичные точки не будут работать, если показатели не совпадают.

ПЕРВОЕ ПРАВИЛО ДОБАВЛЕНИЯ ПЛАВАЮЩЕЙ ТОЧКИ: Определить какой показатель является меньшим показателем. Перепишите это число, используя большее показатель степени, так что теперь два показателя степени совпадают.

В нашем примере второе число имеет меньшую степень (-1).Мы необходимо переписать это число, используя показатель степени 3. Это означает перемещение десятичная запятая 4 разряда слева.

53,21 x 10 -1 = 0,005321 x 10 3

Итак, теперь наше дополнение выглядит так:

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

Помните, что все числа показаны в двоичном формате, поэтому первое число возведен в 1-ю степень.Второе число увеличивается до -2. Нам нужно чтобы переместить второе число из экспоненты -2 в экспоненту 1, перемещая двоичная точка оставила 3 ​​разряда, затем производим сложение.

При работе с числами с плавающей запятой, которые были сохранены в компьютере память, использующая такие форматы, как IEEE 754, должна иметь такой результат, как приведенный выше нормализует его для хранения. Предположим, мы собирались хранить приведенный выше результат в нашем примере 8-битного формата с плавающей запятой (1 знак бит, 3 бита для смещенной экспоненты и 4 бита для мантиссы).Сначала мы будем нужно нормализовать ответ к нормальной экспоненциальной форме.

Далее, поскольку мы можем хранить только 5 бит мантиссы (помните, .1) нам придется усечь все остальные биты. Биты в выделенное ниже поле - это те, которые мы должны усечь.

Теперь о экспоненте. Поскольку у нас есть 3-битное (t = 3) поле для хранения экспоненты, смещение будет 2 t-1 = 2 2 = 4. Итак, магазин экспонента 0, мы должны добавить к ней 4 и сохранить это значение.0 + 4 = 4. Так что предвзятый экспонента (или характеристика) равна 100. 8-битное число, которое мы сохраняем, будет быть:

Рассмотрим два числа с плавающей запятой, хранящиеся в нашем примере 8-битный формат: 10010111 и 11101101. Как их сложить? Сначала напишем их в нормированной экспоненциальной форме.

Первое число имеет меньшую степень (-3), которую мы должны продвигать. к большему показателю (2), добавив 5 0 слева. Итак, теперь мы можем вычислить результат:

Теперь мы нормализуем и усекаем результат до 5-битной мантиссы, чтобы получить:

-.11101 х 10 10

Это число совпадает со вторым числом! Что случилось с первым количество? Оказывается, второе число было настолько маленьким, что при повышении к большему показателю, значащие цифры меньшего числа могут больше не быть представленным. Вы можете видеть, что они были усечены. это как будто мы добавили ноль ко второму числу. Это иллюстрирует виды ошибки, которая может возникнуть при выполнении операций с плавающей запятой.

ВТОРОЕ ПРАВИЛО ДОБАВЛЕНИЯ ПЛАВАЮЩЕЙ ТОЧКИ: Be осторожно при сложении чисел с очень разными показателями, так как значимые может быть внесена ошибка.

Поскольку представление с плавающей запятой является приблизительным, ошибки всегда будут происходить. Уловка состоит в том, чтобы минимизировать влияние ошибок. Что вы можете сделать в ситуации, подобной описанной выше? Лучший ответ использовать более точное представление. Большинство языков программирования предлагают по крайней мере два вида представлений с плавающей запятой. Например, язык программирования C предлагает тип float, который является одиночным precision и тип double, то есть с двойной точностью.В двойной тип следует использовать, когда вы испытываете проблемы с точностью одинарная точность. Однако имейте в виду, что двойной тип требует не только вдвое больше места для хранения (в битах), но и требует больше времени для вычислений. Спецификация IEEE 754 предусматривает как формат с одинарной точностью (который мы видели) и формат двойной точности.

Другие проблемы, которые могут возникнуть при выполнении сложения с плавающей запятой - переполнение и - переполнение .

Переполнение происходит, когда результат имеет слишком большой показатель степени в положительном направлении, что означает, что величина всего числа (положительное или отрицательное число) слишком далеко от нуля быть представленным.Пусть x и -x представляют наибольшее число (положительный и отрицательный) мы можем представить с форматом хранения. Переполнение возникает, если мы пытаемся сохранить число n так, чтобы n <-x или x .

Недополнение происходит, когда результат имеет слишком высокую степень большой в отрицательном направлении, что означает, что величина всего числа (положительное или отрицательное число) лежит между нулем и наименьшая дробь, которую мы можем представить.Пусть x и -x представляют собой наименьшее число (положительное и отрицательное), которое мы можем представить с форматом хранения. Другими словами, единственное, что мы можем представить, между ними лежит ноль. Недополнение происходит, если мы пытаемся сохранить любое число n так, что -x или 0 .

домашних заданий

    Следующие пары байтов являются фактически сохраненными числами с плавающей запятой. в нашем примере формат 1 знаковый бит, 3 бита для смещенной экспоненты и 4 бита для мантиссы (с подразумеваемым '.1 '). Если добавить два байта, и результат сохраняется в том же формате, что и значение байта (битовая комбинация) представлял бы результат? Обязательно укажите, если переполнение или недостаточное количество происходит.
  1. 01001010 + 10010100
  2. 01010011 + 10100100
  3. 00100100 + 10010010
  4. 00001101 + 00001111
  5. 10010011 + 10101100

Следующий модуль: Логические таблицы и таблицы истинности, логические Алгебра
Назад Раздел: Представление с плавающей запятой
Вернуться к Индекс модуля

Арифметика с плавающей запятой | InfoWorld

Добро пожаловать в очередную партию Under The Hood .Эта колонка направлена ​​на то, чтобы дать разработчикам Java представление о скрытой красоте выполняемых ими Java-программ. В колонке этого месяца продолжается начатое в прошлом месяце обсуждение набора команд байт-кода виртуальной машины Java (JVM). В этой статье рассматривается арифметика с плавающей запятой в JVM и рассматриваются байт-коды, которые выполняют арифметические операции с плавающей запятой. В следующих статьях будут обсуждаться другие члены семейства байт-кода.

Основные операции с плавающей запятой

Поддержка операций с плавающей запятой в JVM соответствует стандарту операций с плавающей запятой IEEE-754 1985.Этот стандарт определяет формат 32-битных и 64-битных чисел с плавающей запятой и определяет операции с этими числами. В JVM арифметика с плавающей запятой выполняется с 32-битными числами с плавающей запятой и 64-битными числами с плавающей запятой. Для каждого байт-кода, который выполняет арифметические операции с числами с плавающей запятой, существует соответствующий байт-код, который выполняет ту же операцию с числами типа double.

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

знак * мантисса * основание экспонента

Числа с плавающей запятой имеют несколько представлений, потому что всегда можно умножить мантиссу любого числа с плавающей запятой на некоторую степень основание системы счисления и измените показатель степени, чтобы получить исходное число. Например, число -5 может быть равно любой из следующих форм в системе счисления 10:

Формы -5
Знак Мантисса Основание экспонента
-1 50 10 -1
-1 5 10 0
-1 0.5 10 1
-1 0,05 10 2

Для каждого числа с плавающей запятой существует одно представление, которое считается нормализованным на . Число с плавающей запятой нормализуется, если его мантисса находится в пределах диапазона, определенного следующим соотношением:

1 / radix <= mantissa <1

Нормализованное число с плавающей запятой 10 имеет десятичную точку слева от первого ненулевая цифра мантиссы.Нормализованное представление числа -5 с плавающей запятой: -1 * 0,5 * 10 1 . Другими словами, мантисса нормализованного числа с плавающей точкой не имеет ненулевых цифр слева от десятичной точки и ненулевой цифры справа от десятичной точки. Любое число с плавающей запятой, не попадающее в эту категорию, называется денормализованным . Обратите внимание, что число ноль не имеет нормализованного представления, потому что у него нет ненулевой цифры, которую можно было бы поместить справа от десятичной точки."Зачем быть нормализованным?" это обычное восклицание среди нулей.

Числа с плавающей запятой в JVM используют систему счисления два. Следовательно, числа с плавающей запятой в JVM имеют следующую форму:

знак * мантисса * 2 экспонента

Мантисса числа с плавающей запятой в JVM выражается как двоичное число. У нормализованной мантиссы двоичная точка (эквивалент десятичной точки по основанию два) находится слева от самой значимой ненулевой цифры. Поскольку двоичная система счисления состоит только из двух цифр - нуля и единицы, - самая значимая цифра нормализованной мантиссы всегда равна единице.

Самый старший бит числа с плавающей запятой или двойной точности - это его знаковый бит. Мантисса занимает 23 младших бита числа с плавающей запятой и 52 младших бита числа типа double. Показатель степени, 8 битов с плавающей запятой и 11 битов с двойной точностью, находится между знаком и мантиссой. Формат числа с плавающей запятой показан ниже. Знаковый бит показан как "s", биты экспоненты показаны как "e", а биты мантиссы показаны как "m":

Битовая раскладка Java float
s eeeeeeee ммммммммммммммммммммммм

Знаковый бит, равный нулю, указывает на положительное число, а знаковый бит, равный единице, указывает на отрицательное число.Мантисса всегда интерпретируется как положительное число с основанием два. Это не двоичное дополнение. Если бит знака равен единице, значение с плавающей запятой отрицательно, но мантисса по-прежнему интерпретируется как положительное число, которое необходимо умножить на -1.

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

Мантисса содержит один дополнительный бит точности помимо тех, которые появляются в битах мантиссы. Мантисса числа с плавающей запятой, занимающая всего 23 бита, имеет точность 24 бита. Мантисса числа double, занимающая 52 бита, имеет точность 53 бита. Самый значащий бит мантиссы предсказуем и поэтому не включается, потому что показатель степени чисел с плавающей запятой в JVM указывает, нормализовано ли число.Если показатель степени равен нулю, число с плавающей запятой денормализовано, и известно, что самый значащий бит мантиссы равен нулю. В противном случае число с плавающей запятой нормализуется, и известно, что самый старший бит мантиссы равен единице.

JVM не генерирует исключений в результате каких-либо операций с плавающей запятой. Специальные значения, такие как положительная и отрицательная бесконечность или NaN, возвращаются в результате подозрительных операций, таких как деление на ноль. Показатель всех единиц указывает на специальное значение с плавающей запятой.Показатель всех единиц с мантиссой, все биты которой равны нулю, указывает на бесконечность. Знак бесконечности обозначается битом знака. Показатель всех единиц с любой другой мантиссой интерпретируется как «не число» (NaN). JVM всегда выдает одну и ту же мантиссу для NaN, которая состоит из нулей, за исключением самого значимого бита мантиссы, который появляется в числе. Эти значения показаны ниже для числа с плавающей запятой:

1 11111111 00000000000000000000000
Специальные значения с плавающей запятой
Значение Биты с плавающей запятой (знак экспоненты мантисса)
+ Infinity 0 11111111 00000000000000000000000
NaN 1 11111111 10000000000000000000000

Показатели, не состоящие ни из единиц, ни из нулей, указывают степень двойки, на которую следует умножить нормированную мантиссу.Степень двойки можно определить, интерпретируя биты экспоненты как положительное число, а затем вычитая смещение из положительного числа. Для числа с плавающей запятой смещение равно 126. Для числа с плавающей запятой смещение равно 1023. Например, поле экспоненты в веществе с плавающей запятой, равное 00000001, дает степень двойки путем вычитания смещения (126) из поля экспоненты, интерпретируемого как положительное целое число. (1). Следовательно, степень двойки равна 1 - 126, что составляет -125. Это наименьшая возможная степень двойки для поплавка. С другой стороны, поле экспоненты 11111110 дает степень двойки (254-126) или 128.Число 128 - это наибольшая степень двойки, доступная для поплавка. Несколько примеров нормализованных чисел с плавающей запятой показано в следующей таблице:

-125
Нормализованные значения с плавающей запятой
Значение Биты с плавающей запятой (мантисса знаковой экспоненты) Несмещенная экспонента
Наибольшее положительное (конечное) значение 0 11111110 +11111111111111111111111 128
Самый большой отрицательный (конечное) флоат 1 11111110 +11111111111111111111111 128
Наименьший нормализуется поплавка 1 00000001 +00000000000000000000000
Пи 0 10000000 +10010010000111111011011 2

Показатель степени всех нулей указывает, что мантисса денормализована, что означает, что неустановленный ведущий бит равен нулю, а не единице.Степень двойки в этом случае такая же, как наименьшая степень двойки, доступная для нормализованной мантиссы. Для поплавка это -125. Это означает, что нормализованные мантиссы, умноженные на два в степени -125, имеют поле экспоненты 00000001, тогда как денормализованные мантиссы, умноженные на два в степени -125, имеют поле экспоненты 00000000. Учет денормализованных чисел внизу конец диапазона показателей поддерживает постепенное истощение. Если бы вместо этого для представления нормализованного числа использовался самый низкий показатель степени, то для больших чисел возникло бы уменьшение значения до нуля.Другими словами, оставив самый низкий показатель для денормализованных чисел, можно представить меньшие числа. Меньшие денормализованные числа имеют меньше битов точности, чем нормализованные числа, но это предпочтительнее обнуления до нуля, как только показатель степени достигает минимального нормализованного значения.

000017

0

0

0

0

0 Java float раскрывает свою внутреннюю природу. Апплет, представленный ниже, позволяет вам поиграть с форматом с плавающей запятой.Значение числа с плавающей запятой отображается в нескольких форматах. Формат экспоненциальной системы счисления Radix 2 показывает мантиссу и показатель степени в десятичной системе счисления. Перед отображением фактическая мантисса умножается на 2

24 , что дает целое число, а несмещенная экспонента уменьшается на 24. И целая мантисса, и экспонента затем легко конвертируются в десятичную систему и отображаются.

Потеря точности: советы по работе с сложной арифметикой с плавающей запятой

Мэри Пэт Кэмпбелл

У вас открыт Excel? Поместите это в A1:

= 1 * (.5-.4-.1)

Что вы получили? Если у вас ноль, попробуйте попросить Excel показать вам больше цифр после десятичной точки. Однако, как правило, Excel по умолчанию вернется к следующей нотации с плавающей запятой:

-2,78E-17

Конечно, это мало, но это не ноль.

Отдельно, если вы ознакомитесь с моей таблицей из январского выпуска CompAct за 2014 г. -14).Это может вызвать у нас проблемы с некоторыми приложениями дистрибутива. Вычисленные числа должны составлять в сумме один, по крайней мере, для вкладок, не использующих приближения, если бы мы использовали точную арифметику, карандаш и бумагу. Но не в Excel.

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

Во-первых, что такое представление действительного числа с плавающей запятой? Выглядит это так:

(+/-) Знаки * основание экспонента

В стандартных формах

обычно указывается, что значение «Significand» находится в диапазоне от 0,0 до 9,999999 (на уровне точности станка). База будет указана (обычно две для компьютеров). Каждая система будет иметь ограничения на количество значащих цифр (так называемая точность), а также будут ограничения на показатель степени (положительный и отрицательный).Между положительными и отрицательными числами может существовать некоторая асимметрия, поэтому наименьшее отрицательное число может не совпадать по абсолютной величине с наибольшим положительным числом в системе (аналогично для диапазона показателей).

Для преувеличения эффекта арифметических операций с плавающей запятой я буду использовать некоторые довольно низкие ограничения. Я разрешаю до четырех значащих цифр (от -9,999 до 9,999), я разрешаю экспоненты от отрицательных трех до четырех, и я буду использовать основание 10 для облегчения ручной проверки операций.

Давайте рассмотрим некоторые проблемы, связанные с арифметикой с плавающей запятой:

  1. Перелив
  2. Отпуск
  3. Потеря точности при преобразовании в числа с плавающей запятой
  4. Сложение чисел очень разных величин
  5. Вычитание чисел одинаковой величины
  6. Умножение и деление

Переполнение
Переполнение происходит, когда число, которое вы пытаетесь выразить с плавающей запятой, слишком велико по величине.-4.

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

.

Хороший способ представить это в терминах значащих цифр и того, что система накладывает ограничение на количество разрешенных сигнатур.-1? То есть мы пытаемся добавить 777,7 к 0,9555.

В точной арифметике ответ 778,6555. Но это слишком много значащих цифр для нашей системы с плавающей запятой. Мы должны округлить это число до 778,7, чтобы оно соответствовало нашей системе. Разница между округленным ответом и нашим точным ответом составляет 0,0445. В относительном выражении это незначительная ошибка, так что, может быть, нас это не беспокоит.

Но что должно нас беспокоить, так это когда мы делаем что-то вроде сложения кучи чисел, которые в конечном итоге должны быть в сумме до одного, но каждое из них очень мало.-1. В нашей системе это выглядит так: 0,9999 + 0,00001 = 0,99991 = 0,9999. Теперь предположим, что мы пытаемся добавить этот столбец чисел:

Денормализованные значения с плавающей запятой
Значение Биты с плавающей запятой (мантисса знаковой экспоненты)
Наименьшее положительное (ненулевое) с плавающей запятой 0 00000000 00000000000000000000001 Наименьшее отрицательное значение float 1 00000000 00000000000000000000001
Наибольшее денормализованное число с плавающей запятой 1 00000000 11111111111111111111111
Положительный ноль 0 00000000 0000000000003 0 00000000 000000000000000
.9999
.00001
.00001
.00001
.00001
.00001
.00001
.00001
.00001
.00001
.-3 будет похоже на прибавление нуля к 0,9999.

Итак, как с этим справиться?

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

При простом подходе вы добавляете этот столбец чисел снизу вверх, а затем они складываются до 1. Обратите внимание, что сложение с плавающей запятой не ассоциативно. Разве это не интересно?

Другой подход - сложить каждое из этих наименьших чисел парами, а затем сложить эти пары друг с другом.-3.

Совет 2: Перед вычитанием чисел с плавающей запятой вам может потребоваться «массировать» исходные числа или изменить алгоритм, чтобы не терять значащие цифры при вычитании.

Просмотрите ссылку на Википедию в ресурсах, чтобы увидеть примеры потери значимости, особенно в формуле квадратного уравнения, когда b велико, а 4ac очень мало.

Умножение и деление
Проблема с умножением и делением - это проблема переполнения и потери значимости.

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

Используя нашу систему, предположим, вы хотите сделать:

(99990 * 19990 * 22220) / (11110 * 77770)

Если бы мы делали это при вычислении строго слева направо, то при первой операции у нас было бы переполнение.4 (в нашей системе)

Совет 3: Чтобы предотвратить переполнение и потерю точности (а также потерю точности) при умножении и делении чисел, попробуйте переставить произведение так, чтобы при умножении на числа, близкие к единице.

Еще можно попробовать преобразовать продукты в суммы с помощью логарифмов. Давайте представим, что наша функция log (base 10) работает аналогично нашей системе с плавающей запятой.

Тогда получаем: log (99990) + log (19990) + log (22220) - log (11110) - log (77770) = 4.4

Таким образом, мы получаем небольшую потерю точности в этом подходе, но сделать это преобразование может быть проще, чем пытаться перемешивать члены в вычислениях. Я пробовал оба этих подхода в задаче биномиального приближения с переменным успехом.

Совет 4. Иногда преобразование вычислений путем применения функции (например, логарифмов) может устранить опасность переполнения или потери значимости, хотя это может стать новым источником потери точности.

Источник: Сайт xkcd

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

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

Ресурсы и ссылки

Предыдущие статьи автора по теме

Внешние ресурсы

Мэри Пэт Кэмпбелл, FSA, MAAA, аналитик компании Conning Research & Consulting, Inc.С ней можно связаться по адресу [email protected]

Семантика операций с плавающей запятой - Руководство пользователя SPARK 22.0w

SPARK предполагает, что операции с плавающей запятой выполняются за один точность (binary32) или двойная точность (binary64), как определено в IEEE-754 стандарт для арифметики с плавающей запятой. Вы должны убедиться, что это чехол на вашей платформе. Например, на платформах x86 по умолчанию некоторые промежуточные вычисления могут выполняться с повышенной точностью, что приводит к неожиданные результаты.С GNAT / GCC вы можете указать использование арифметики SSE с помощью используя переключатели компиляции -msse2 -mfpmath = sse , которые вызывают все арифметические действия должны выполняться с использованием набора инструкций SSE, который обеспечивает только 32-разрядные и 64-битные типы IEEE и не обеспечивают расширенной точности. Арифметика SSE также более эффективен. Обратите внимание, что ABI позволяет свободно смешивать единицы, используя два типа с плавающей запятой, поэтому нет необходимости заставлять все единицы в программа для использования арифметики SSE.

Некоторые архитектуры также имеют инструкции слияния-множественного добавления (FMA), либо в базовом наборе (PowerPC, Aarch64) или в расширениях (SPARC, x86).Вам следует убедитесь, что ваш компилятор проинструктирован не использовать такие инструкции, чьи влияние на семантику программы не может быть учтено источником SPARK анализ кода. На x86 такие инструкции включены в GNAT / GCC с помощью явный переключатель, например -fma / -fma4 , или переключатели архитектуры, например -msse4.1 или -mavx512f , поэтому убедитесь, что вы их не используете. С участием GNAT / GCC, рекомендуется использовать переключатель -ffp-contract = off , чтобы отключить все сокращение выражений с плавающей запятой, включая FMA.

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

SPARK рассматривает округление арифметических операций с плавающей запятой, чтобы следовать Режим Round-Nearest-Even (RNE), в котором реальный результат округляется до ближайшего значение с плавающей запятой, и связи разрешаются с плавающей запятой с нулем в последнюю очередь.

Author: alexxlab

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *