8-900-374-94-44
[email protected]
Slide Image
Меню

Числа с плавающей точкой в с: Числовые типы с плавающей запятой — справочник по C#

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

Содержание:

  • Вступление
  • Экскурс в историю
  • Формат записи числа с плавающей точкой
  • Знак и степень
  • Мантисса
  • Итоги
Изображение: 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×2
0
= 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.: В виде домашнего задания, используя эту статью, оставьте в комментариях свои версии, почему при большом количестве арифметических операций с числами с плавающей точкой возникают ошибки точности

Числа с плавающей точкой | это… Что такое Числа с плавающей точкой?

Структура числа

Число с плавающей запятой состоит из:

  • Мантиссы (выражающей значение числа без учёта порядка)
  • Знака мантиссы (указывающего на отрицательность или положительность числа)
  • Порядка (выражающего степень основания числа, на которое умножается мантисса)
  • Знака порядка

Нормальная форма

Нормальной формой числа с плавающей запятой называется такая форма, в которой мантисса (без учёта знака) находится на полуинтервале [0; 1).

Число с плавающей запятой, находящееся не в нормальной форме теряет точность по сравнению с нормальной формой. Такая форма записи имеет недостаток: некоторые числа записываются неоднозначно (например, 0,0001 можно записать в 4 формах — 0,0001 * 100, 0,001 * 10-1, 0,01 * 10-2, 0,1 * 10-3), поэтому распространена (особенно в информатике) также другая форма, в которой мантисса принимает значения от 1 (включительно) до 10 (не включительно). В такой форме любое число (кроме 0) записывается единственным образом. Недостаток заключается в том, что в таком виде невозможно представить 0, поэтому представление чисел в информатике предусматривает специальный признак (бит) для числа 0.

Использование в вычислительных машинах

В вычислительных машинах показатель степени принято отделять от мантиссы буквой «E» (exponent). Например, число 1,528535047 × 10

-25 в большинстве языков программирования высокого уровня записывается как 1.528535047E-25.

Краткий обзор

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

  • Наиболее распространённый путь представления значения числа из строки с цифрами — в виде целого числа — запятая (radix point) по-умолчанию находится в конце строки.
  • В общем математическом представлении строка из цифр может быть сколь угодно длинной, а положение запятой обозначается путём явной записи символа запятой (или, на Западе, точки) в нужном месте.
  • В системах с представлением чисел в формате с фиксированной запятой существует определённое условие относительно положения запятой. Например, в строке из 8 цифр условие может предписывать положение запятой в середине записи (между 4-й и 5-й цифрой). Таким образом, строка «00012345» обозначает число 1,2345 (нули слева всегда можно отбросить).
  • В экспоненциальной записи используют стандартный (нормальный?) вид представления чисел. Число считается записанным в стандартном виде, если оно записано в виде aqn, где a такое, что , называется мантиссой, n — целое, называется показатель степени и q — целое, основание системы счисления (на письме это обычно 10). То есть в мантиссе запятая помещается сразу после первой значащей (не равной нулю) цифры, считая слева направо, а дальнейшая запись даёт информацию о действительном значении числа. Например, период обращения (на орбите) спутника планеты Юпитера Ио́, который равен 152853,5047 с, в стандартном виде можно записать как 1,528535047 × 105. Побочным эффектом ограничения на значения мантиссы является то, что в такой записи невозможно изобразить число 0.
  • Запись в форме с плавающей запятой похожа на запись чисел в стандартном виде, но мантисса и экспонента записываются раздельно. Мантисса записывается в формате с фиксированной запятой, подразумеваемой после первой цифры. Возвращаясь к примеру с Ио́, запись в форме с плавающей запятой будет 1528535047 с показателем 5. Это означает, что записанное число в 105 раз больше числа 1,528535047, то есть для получения подразумеваемого числа запятая сдвигается на 5 разрядов вправо. Однако, запись в форме с плавающей запятой используется в основном в электронном представлении чисел, при котором используется основание системы счисления 2, а не 10. Кроме того, в двоичной записи мантисса обычно денормализована, то есть запятая подразумевается до первой цифры, а не после, и целой части вообще не имеется ввиду — так появляется возможность и значение 0 сохранить естественным образом. Таким образом, десятичная 9 в двоичном представлении с плавающей запятой будет записана как мантисса +1001000…0 и показатель +0…0100. Отсюда, например, беды с двоичным представлением чисел типа одной десятой (0,1), для которой двоичное представление мантиссы оказывается периодической двоичной дробью — по аналогии с 1/3, которую нельзя конечным количеством цифр записать в десятичной системе счисления.

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

0,12 × 0,12 = 0,0144

в нормальной форме представляется в виде

(1,20 × 10−1) × (1,20 × 10−1) = (1,44 × 10−2).

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

0,120 × 0,120 = 0,014.

Мы потеряли крайний правый разряд числа, так как данный формат не позволяет запятой «плавать» по записи числа.

Диапазон чисел, представимых в формате с плавающей запятой

Диапазон чисел, которые можно записать данным способом, зависит от количества бит, отведённых для представления мантиссы и показателя. На обычной 32-битной вычислительной машине, использующей двойную точность (64 бита), мантисса составляет 52 бита + 1 знаковый, показатель — 11 бит. Таким образом получаем диапазон точности примерно от 4,94 × 10−324 до 1.79 × 10308 (от 2−52 × 2−1022 до ~1 × 21024). Пара значений показателя зарезервирована для обеспечения возможности представления специальных чисел. К ним относятся значения бесконечность), получающихся в результате операций типа деления на ноль нуля, положительных и отрицательных чисел. 2\text{kg}/\text{s}\). Если мы изменим только последнюю цифру с \(8\) на \(9{-15}\), в котором по-прежнему 7 цифр, но только 21 десятичный знак.

Можно легко спутать термины точность и точность , особенно если посмотреть на результат вычисления на компьютере. Точность числа с плавающей запятой всегда равна \(d\) двоичным разрядам, но не все эти разряды могут точно представлять предполагаемое значение.

Предположим, что \(x\) представляет интерес, а \(\tilde{x}\) является его приближением. Абсолютная точность из \(\tilde{x}\) равно

\[|\tilde{x} — x|,\]

, а относительная точность равна

\[\frac{|\tilde{x} — x|}{|x|},\]

Абсолютная точность имеет те же единицы измерения, что и \(x\), а относительная точность безразмерна. Мы также можем выразить относительную точность как

(5)\[\text{точные цифры} = -\log_{10} \left| \frac{\tilde{x}-x}{x} \right|.\]

Мы часто округляем это число до целого числа, но имеет смысл говорить о «почти семизначном» или «десяти с половиной цифрах». цифры». 9{-1022}\), что является наименьшим положительным числом двойной точности. Первое связано с относительной точностью, а второе — с абсолютной точностью. Чтобы приблизиться к нулю, всегда требуется сдвиг мышления в сторону абсолютной точности, потому что любая конечная ошибка бесконечна по отношению к нулю.

Следует отметить еще одно значение двойной точности: NaN, что означает Not a Number . Это результат неопределенной арифметической операции, такой как 0/0.

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

Компьютерная арифметика выполняется над числами с плавающей запятой и возвращает результаты с плавающей запятой. Мы предполагаем существование машинно-аналоговых операций для вещественных функций, таких как \(+\), \(-\), \(\times\), \(/\), \(\sqrt{\quad}\), и так далее. Не вдаваясь в подробности, предположим, что каждая элементарная машинная операция создает результат с плавающей запятой, относительная погрешность которого ограничена \(\macheps\). Например, если \(x\) и \(y\) находятся в \(\float\), то для машинного сложения \(\oplus\) мы имеем оценку 9{-16}\), что очень мало — не только в повседневном исчислении, но и по отношению к операндам, которые по модулю близки к 1. С другой стороны, разница столь же велика, как и сам точный результат! Мы формализуем и обобщим это наблюдение в следующем разделе. В то же время имейте в виду, что точность вычислений с плавающей запятой не может считаться само собой разумеющейся. Даже в идеале мы не должны ожидать, что два математически эквивалентных результата будут равны, а только то, что они будут относительно близки друг к другу.

Упражнения

  1. ✍ Рассмотрим множество с плавающей запятой \(\float\), определяемое (1) и (2) с \(d=4\).

    (a) Сколько элементов \(\float\) есть в действительном интервале \([1/2,4]\), включая конечные точки?

    (b) Какой элемент \(\float\) ближе всего к действительному числу \(1/10\)?

    (c) Какое наименьшее натуральное число не входит в \(\float\)?

  2. ✍ Докажите, что (3) эквивалентно (4). (Это означает сначала показать, что из (3) следует (4), а затем отдельно, что из (4) следует (3).)

  3. ⌨ Существуют гораздо лучшие рациональные приближения к \(\pi\), чем \(22/7\). Для каждого из приведенных ниже найдите его абсолютную и относительную точность и (округлив до целого числа) количество точных цифр. (В Julia переменная pi по умолчанию настроена на приближение с плавающей запятой к \(\pi\).)

    (а) 355/113

    (б) 103638/32989

  4. ✍ IEEE 754 одинарная точность указывает, что 23 двоичных бита используются для мантиссы \(f\) в (2). Поскольку они требуют меньше места для хранения и могут работать быстрее, чем значения двойной точности, значения одинарной точности могут быть полезны в приложениях с низкой точностью.

    (a) В десятичной системе счисления какое первое число одинарной точности больше \(1\) в этой системе?

    (b) Какое наименьшее положительное целое число не является числом одинарной точности?

  5. ⌨ Джулия определяет функцию nextfloat , которая возвращает следующее большее значение заданного числа с плавающей запятой. 2}{2n}=1.\] 94\):

     r = randn(10000) # рисуем случайные числа
    х = сумма (знак (z) для z в r)
     

    Выполнить миллион случайных обходов, вычислив средние значения \(x_{10000}\) и \(|x_{10000}|\). Сравните их с \(\alpha_n=0\) и \(\beta_n\приблизительно \sqrt{2n/\pi}\) в \(n=10000\).


1

Термины «машинный эпсилон», «машинная точность» и «округление единиц» не используются последовательно в ссылках, но для наших целей различия незначительны.

2

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

Визуальное объяснение операций с плавающей запятой

Визуальное объяснение операций с плавающей запятой

ВЕБ-САЙТ FABIEN SANGLARD


29 августа 2017 г.

Визуальное объяснение операций с плавающей запятой


9{(E-127)}$ и его таинственная экспонента/мантисса. Возможно, рисунок, так как они, кажется, лучше проходят через мой мозг.

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

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


В языке C плавает представляют собой 32-битный контейнер, соответствующий стандарту IEEE 754. Их назначение – хранить и позволять операции по приближению действительных чисел. То, как я видел их объяснение до сих пор, выглядит следующим образом. 32 бита разделены на три части: 9{(E-127)} $$

Как все ненавидят числа с плавающей запятой, когда им объясняют.

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

Многие считают арифметику с плавающей запятой эзотерической темой.

— Дэвид Голдберг

Другой способ объяснить…


Хотя это правильно, такой способ объяснения плавающей запятой оставляет некоторых из нас совершенно непонятными. невежественный. К счастью, есть другой способ объяснить это. Вместо экспоненты подумайте Окна между двумя последовательными степенями двух целых чисел. Вместо мантиссы подумайте смещения в этом окне. 9{23} = 8388608 $ ведер. С окном и смещением вы можете аппроксимировать число. Окно – отличный механизм для защиты от перелива. Как только вы достигли максимума в окне (например, [2,4]), вы можете «переместить» его вправо и представить число в следующем окне (например, [4,8]). Это стоит лишь немного точности, так как окно становится вдвое больше.

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

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

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