Что такое плавающая точка на клавиатуре

Обновлено: 18.05.2024

Такой метод является компромиссом между точностью и диапазоном представляемых значений. Представление чисел с плавающей точкой рассмотрим на примере чисел двойной точности (double precision). Такие числа занимают в памяти два машинных слова (8 байт на 32-битных системах). Наиболее распространенное представление описано в стандарте IEEE 754.

Кроме чисел двойной точности также используются следующие форматы чисел:

  • половинной точности (half precision) (16 бит),
  • одинарной точности (single precision) (32 бита),
  • четверной точности (quadruple precision) (128 бит),
  • расширенной точности (extended precision) (80 бит).

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

Недостатком такой записи является тот факт, что числа нельзя записать однозначно: [math] 0.01 = 0.001 \times 10^1 [/math] .

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

  1. знак
  2. экспонента (показатель степени) (в виде целого числа в коде со сдвигом)
  3. мантисса (в нормализованной форме)

В качестве базы (основания степени) используется число [math] 2 [/math] . Экспонента хранится со сдвигом [math] -1023 [/math] .

Итоговое значение числа вычисляется по формуле:
[math] x = (-1)^ \times (1.mant) \times 2^ [/math] .
  1. В нормализованном виде любое отличное от нуля число представимо в единственном виде. Недостатком такой записи является тот факт, что невозможно представить число 0.
  2. Так как старший бит двоичного числа, записанного в нормализованной форме, всегда равен 1, его можно опустить. Это используется в стандарте IEEE 754.
  3. В отличие от целочисленных стандартов (например, integer), имеющих равномерное распределение на всем множестве значений, числа с плавающей точкой (double, например) имеют квазиравномерное распределение.
  4. Вследствие свойства 3, числа с плавающей точкой имеют постоянную относительную погрешность (в отличие от целочисленных, которые имеют постоянную абсолютную погрешность).
  5. Очевидно, не все действительные числа возможно представить в виде числа с плавающей точкой.
  6. Точно в таком формате представимы только числа, являющиеся суммой некоторых обратных степеней двойки (не ниже -53). Остальные числа попадают в некоторый диапазон и округляются до ближайшей его границы. Таким образом, абсолютная погрешность составляет половину величины младшего бита.
  7. В формате double представимы числа в диапазоне [math] [2.3 \times 10^, 1.7 \times 10^] [/math] .

В нормализованной форме невозможно представить ноль. Для его представления в стандарте зарезервированы специальные значения мантиссы и экспоненты.

Согласно стандарту выполняются следующие свойства:

  • [math] +0 = -0 [/math]
  • [math] \frac< \left| x \right| >= -0\,\![/math] (если [math]x\ne0[/math] )
  • [math] (-0) \cdot (-0) = +0\,\![/math]
  • [math] \left| x \right| \cdot (-0) = -0\,\![/math]
  • [math] x + (\pm 0) = x\,\![/math]
  • [math] (-0) + (-0) = -0\,\![/math]
  • [math] (+0) + (+0) = +0\,\![/math]
  • [math] \frac<-\infty>= +0\,\![/math]
  • [math] \frac<\left|x\right|>= -\infty\,\![/math] (если [math]x\ne0[/math] )

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

Бесконечное значение можно получить при переполнении или при делении ненулевого числа на ноль.

В математике встречается понятие неопределенности. В стандарте double предусмотрено псевдочисло, которое арифметическая операция может вернуть даже в случае ошибки.

Неопределенность можно получить в нескольких случаях. Приведем некоторые из них:

  • [math] f(NaN) = NaN [/math] , где [math] f [/math] - любая арифметическая операция
  • [math] \infty + (-\infty) = NaN [/math]
  • [math] 0 \times \infty = NaN [/math]
  • [math] \frac<\pm0><\pm0>= \frac<\pm \infty><\pm \infty>= NaN [/math]
  • [math] \sqrt = NaN [/math] , где [math] x \lt 0 [/math]

Денормализованные (denormalized numbers) - способ увеличить количество представимых числе в окрестности нуля. Каждое такое число по модулю меньше самого маленького нормализованного.< Согласно стандарту числа с плавающей точкой можно представить в следующем виде:

  • [math] (-1)^s \times 1.M \times 2^E [/math] , в нормализованном виде если [math] E_ \leq E \leq E_ [/math] ,
  • [math] (-1)^s \times 0.M \times 2^E_ [/math] , в денормализованном виде если [math] E = E_ - 1 [/math] ,

где [math] E_ [/math] - минимальное значение порядка, используемое для записи чисел (единичный сдвиг), [math] E_ - 1 [/math] - минимальное значение порядка, которое он может принимать - все биты нули, нулевой сдвиг.

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

  1. Flush To Zero (FTZ) - в качестве результата возвращается нуль, как только становится понятно, что результат будет представляться в денормализованном виде.
  2. Denormals Are Zero (DAZ) - денормализованные числа, поступающие на вход, рассматриваются как нули.

Начиная с версии стандарта IEEE 754 2008 года денормализованные числа называются "субнормальными" (subnormal numbers), то есть числа, меньшие "нормальных".

Таким образом, компьютер не различает числа [math] x [/math] и [math] y [/math] , если [math] 1 \lt \frac \lt 1 + \varepsilon_m [/math] . Из свойств чисел двойной точности следует, что для них [math] \varepsilon_m = 2^<-54>[/math] .

Мера единичной точности используется для оценки точности вычислений.


Приведем пример кода на Python, который показывает, при каком значении числа [math] x [/math] компьютер не различает числа [math] x [/math] и [math] x + 1 [/math] .

То есть [math] x = 2^ [/math] , так как мантисса числа двойной точности содержит 53 бита (в памяти хранятся 52). В C++ для расчета расстояния между двумя числами двойной точности можно воспользоваться функцией [math] \mathrm [/math] .

  • [math] a \oplus b = (a + b) (1 + \delta), |\delta| \leq \varepsilon_m [/math] ,
  • [math] a \ominus b = (a - b) (1 + \delta), |\delta| \leq \varepsilon_m [/math] ,
  • [math] a \otimes b = ab (1 + \delta), |\delta| \leq \varepsilon_m [/math] .
[math] \forall a, b, c \in D^2, \tilde = (b_x \ominus a_x) \otimes (c_y \ominus a_y) \ominus (b_y \ominus a_y) \otimes (c_x \ominus a_x) [/math]

[math] \exists \tilde \in D: [/math]

  1. [math] \tilde \gt \tilde \Rightarrow (b - a) \times (c - a) \gt 0 [/math]
  2. [math] \tilde \lt -\tilde \Rightarrow (b - a) \times (c - a) \lt 0 [/math]

Обозначим [math] v = (b - a) \times (c - a) = (b_x - a_x) (c_y - a_y) - (b_y - a_y) (c_x - a_x)[/math] .

Теперь распишем это выражение в дабловой арифметике.

[math]\tilde = (b_x \ominus a_x) \otimes (c_y \ominus a_y) \ominus (b_y \ominus a_y) \otimes (c_x \ominus a_x) = \\ = [ (b_x - a_x) (c_y - a_y) (1 + \delta_1) (1 + \delta_2) (1 + \delta_3) - \\ - (b_y - a_y) (c_x - a_x) (1 + \delta_4) (1 + \delta_5) (1 + \delta_6) ] (1 + \delta_7),[/math]

[math] |\delta_i| \leq \varepsilon_m [/math]

Заметим, что [math] v \approx \tilde [/math]

Теперь оценим абсолютную погрешность [math] \epsilon = |v - \tilde|. [/math]

[math] |v - \tilde| = |(b_x - a_x) (c_y - a_y) - (b_y - a_y) (c_x - a_x) - \\ - (b_x - a_x) (c_y - a_y) (1 + \delta_1) (1 + \delta_2) (1 + \delta_3) (1 + \delta_7) + \\ + (b_y - a_y) (c_x - a_x) (1 + \delta_4) (1 + \delta_5) (1 + \delta_6) (1 + \delta_7)| = \\ = |(b_x - a_x) (c_y - a_y) (1 - (1 + \delta_1) (1 + \delta_2) (1 + \delta_3) (1 + \delta_7)) - \\ - (b_y - a_y) (c_x - a_x) (1 - (1 + \delta_4) (1 + \delta_5) (1 + \delta_6) (1 + \delta_7))| \leq \\ \leq |(b_x - a_x) (c_y - a_y) (1 - (1 + \delta_1) (1 + \delta_2) (1 + \delta_3) (1 + \delta_7))| + \\ + |(b_y - a_y) (c_x - a_x) (1 - (1 + \delta_4) (1 + \delta_5) (1 + \delta_6) (1 + \delta_7))| = \\ = |(b_x - a_x) (c_y - a_y)| \cdot |((1 + \delta_1) (1 + \delta_2) (1 + \delta_3) (1 + \delta_7) - 1)| + \\ + |(b_y - a_y) (c_x - a_x)| \cdot |((1 + \delta_4) (1 + \delta_5) (1 + \delta_6) (1 + \delta_7) - 1)| = \\ = |(b_x - a_x) (c_y - a_y)| \cdot |\delta_1 + \delta_2 + \delta_3 + \delta_7 + \delta_1 \delta_2 \ldots| + \\ + |(b_y - a_y) (c_x - a_x)| \cdot |\delta_4 + \delta_5 + \delta_6 + \delta_7 + \delta_4 \delta_5 \ldots| \leq \\ \leq |(b_x - a_x) (c_y - a_y)| \cdot (|\delta_1| + |\delta_2| + |\delta_3| + |\delta_7| + |\delta_1 \delta_2| \ldots) + \\ + |(b_y - a_y) (c_x - a_x)| \cdot (|\delta_4| + |\delta_5| + |\delta_6| + |\delta_7| + |\delta_4 \delta_5| \ldots) \leq \\ \leq |(b_x - a_x) (c_y - a_y)| \cdot (4 \varepsilon_m + 6 \varepsilon_m^2 + 4 \varepsilon_m^3 + \varepsilon_m^4) + \\ + |(b_y - a_y) (c_x - a_x)| \cdot (4 \varepsilon_m + 6 \varepsilon_m^2 + 4 \varepsilon_m^3 + \varepsilon_m^4) = \\ = (|(b_x - a_x) (c_y - a_y)| + |(b_y - a_y) (c_x - a_x)|)(4 \varepsilon_m + 6 \varepsilon_m^2 + 4 \varepsilon_m^3 + \varepsilon_m^4)[/math]

Пусть [math] t = (|(b_x - a_x) (c_y - a_y)| + |(b_y - a_y) (c_x - a_x)|).[/math] Получаем, что

[math] \epsilon = |v - \tilde| \leq t \cdot (4 \varepsilon_m + 6 \varepsilon_m^2 + 4 \varepsilon_m^3 + \varepsilon_m^4). [/math]

[math]\tilde = (|(b_x - a_x) (c_y - a_y) (1 + \delta_1) (1 + \delta_2) (1 + \delta_3)| + \\ + |(b_y - a_y) (c_x - a_x) (1 + \delta_4) (1 + \delta_5) (1 + \delta_6)|) (1 + \delta_7) \geq \\ \geq |(b_x - a_x) (c_y - a_y) (1 - \varepsilon_m)^3)|(1 - \varepsilon_m) + \\ + |(b_y - a_y) (c_x - a_x) (1 - \varepsilon_m)^3)|(1 - \varepsilon_m) = \\ = |(b_x - a_x) (c_y - a_y)| (1 - \varepsilon_m)^4 + |(b_y - a_y) (c_x - a_x)| (1 - \varepsilon_m)^4 = \\ = (|(b_x - a_x) (c_y - a_y)| + |(b_y - a_y) (c_x - a_x)|) (1 - \varepsilon_m)^4 = t \cdot (1 - \varepsilon_m)^4[/math]

[math] t \leq \tilde \frac <(1 - \varepsilon_m)^4>= \tilde (1 + 4 \varepsilon_m + 10 \varepsilon_m^2 + 20 \varepsilon_m^3 + \cdots) [/math]

[math] \epsilon = |v - \tilde| \leq \tilde \leq \tilde (1 + 4 \varepsilon_m + 10 \varepsilon_m^2 + 20 \varepsilon_m^3 + \cdots) (4 \varepsilon_m + 6 \varepsilon_m^2 + 4 \varepsilon_m^3 + \varepsilon_m^4) [/math]

[math] \tilde \lt 8 \varepsilon_m \tilde [/math]

Заметим, что это довольно грубая оценка. Вполне можно было бы написать [math] \tilde \lt 4.25 \varepsilon_m \tilde [/math] или [math] \tilde \lt 4.5 \varepsilon_m \tilde.[/math]

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

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

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

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

  • N = 1200 — получаемое число
  • M = 1,2 — мантисса — дробная часть, без учёта порядков
  • n = 10 — основание порядка. В данном случае и когда речь не идёт о компьютерах, основанием выступает цифра 10
  • p = 3 — степень основания

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

Что внутри числа с плавающей точкой и как оно работает - 1

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

Мантисса

Что внутри числа с плавающей точкой и как оно работает - 3

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

Итоги

Что внутри числа с плавающей точкой и как оно работает - 5

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

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

Содержание

«Плавающая запятая» и «плавающая точка»

Так как в некоторых, преимущественно англоязычных и англофицированных, странах (см. подробный список Decimal separator (англ.) ) при записи чисел целая часть отделяется от дробной точкой, то в терминологии этих стран фигурирует название «плавающая точка» (floating point (англ.) ). Так как в России целая часть числа от дробной традиционно отделяется запятой, то для обозначения того же понятия используется термин «плавающая запятая».

Происхождение названия

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

Преимущество использования представления чисел в формате с плавающей запятой над представлением в формате с фиксированной запятой (и целыми числами) состоит в том, что можно использовать существенно больший диапазон значений при неизменной относительной точности. Например, в форме с фиксированной запятой число, занимающее 8 разрядов в целой части и 2 разряда после запятой, может быть представлено в виде 123456,78; 8765,43; 123,00 и так далее. В свою очередь, в формате с плавающей запятой (в тех же 8 разрядах) можно записать числа 1,2345678; 1234567,8; 0,000012345678; 12345678000000000 и так далее.

Скорость выполнения компьютером операций с числами, представленными в форме с плавающей запятой, измеряется в англ. FLOPS — число операций с плавающей запятой в секунду ),

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

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

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

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

Нормальной формой числа с плавающей запятой называется такая форма, в которой мантисса (без учёта знака) находится на полуинтервале [0; 1). Число с плавающей запятой, находящееся не в нормальной форме теряет точность по сравнению с нормальной формой. Такая форма записи имеет недостаток: некоторые числа записываются неоднозначно (например, 0,0001 можно записать в 4 формах - 0,0001 * 10 0 , 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.

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

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

1\le a&amp;lt;q

  • Наиболее распространённый путь представления значения числа из строки с цифрами — в виде целого числа — запятая (radix point) по-умолчанию находится в конце строки.
  • В общем математическом представлении строка из цифр может быть сколь угодно длинной, а положение запятой обозначается путём явной записи символа запятой (или, на Западе, точки) в нужном месте.
  • В системах с представлением чисел в формате с фиксированной запятой существует определённое условие относительно положения запятой. Например, в строке из 8 цифр условие может предписывать положение запятой в середине записи (между 4-й и 5-й цифрой). Таким образом, строка "00012345" обозначает число 1,2345 (нули слева всегда можно отбросить).
  • В экспоненциальной записи используют стандартный (нормальный?) вид представления чисел. Число считается записанным в стандартном виде, если оно записано в виде aqn , где a такое, что , называется мантиссой, n — целое, называется показатель степени и q — целое, основание системы счисления (на письме это обычно 10). То есть в мантиссе запятая помещается сразу после первой значащей (не равной нулю) цифры, считая слева направо, а дальнейшая запись даёт информацию о действительном значении числа. Например, период обращения (на орбите) спутника планеты ЮпитераИо́, который равен 152853,5047 с, в стандартном виде можно записать как 1,528535047 × 10 5 . Побочным эффектом ограничения на значения мантиссы является то, что в такой записи невозможно изобразить число 0.
  • Запись в форме с плавающей запятой похожа на запись чисел в стандартном виде, но мантисса и экспонента записываются раздельно. Мантисса записывается в формате с фиксированной запятой, подразумеваемой после первой цифры. Возвращаясь к примеру с Ио́, запись в форме с плавающей запятой будет 1528535047 с показателем 5. Это означает, что записанное число в 10 5 раз больше числа 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 × 10 308 (от 2 −52 × 2 −1022 до

1 × 2 1024 ). Пара значений показателя зарезервирована для обеспечения возможности представления специальных чисел. К ним относятся значения бесконечность), получающихся в результате операций типа деления на ноль нуля, положительных и отрицательных чисел. Также сюда попадают денормализованные числа, у которых мантисса меньше единицы. В специализированных устройствах (например GPU) поддержка специальных чисел часто отсутствует. Существуют программные пакеты, в которых объём памяти выделенный под мантиссу и показатель задаётся программно, и ограничивается лишь объёмом доступной памяти ЭВМ.

Машинный эпсилон

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

Машинным эпсилоном называется наименьшее положительное число ε такое, что (знаком обозначено машинное сложение). Грубо говоря, числа a и b, соотносящиеся так, что , машина не различает.

См. также

Литература

  • Н. А. Криницкий, Г. А. Миронов, Г. Д. Фролов. Программирование. — Государственное издательство физико-математической литературы. — Москва, 1963
  • Генри С. Уоррен, мл.Глава 15. Числа с плавающей точкой // Алгоритмические трюки для программистов = Hacker's Delight. — М.: «Вильямс», 2007. — С. 288. — ISBN 0-201-91465-4 коды с фиксированной запятой

Wikimedia Foundation . 2010 .

Полезное

Смотреть что такое "Плавающая точка" в других словарях:

плавающая точка — плавающая запятая — [Е.С.Алексеев, А.А.Мячев. Англо русский толковый словарь по системотехнике ЭВМ. Москва 1993] Тематики информационные технологии в целом Синонимы плавающая запятая EN floating pointFP … Справочник технического переводчика

плавающая точка начала байта — — [Л.Г.Суменко. Англо русский словарь по информационным технологиям. М.: ГП ЦНИИС, 2003.] Тематики информационные технологии в целом EN floating byte … Справочник технического переводчика

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

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

Есть три типа данных с плавающей точкой: float, double и long double. Язык C++ определяет только их минимальный размер (как и с целочисленными типами). Типы данных с плавающей точкой всегда являются signed (т.е. могут хранить как положительные, так и отрицательные числа).

Тип Минимальный размер Типичный размер
Тип данных с плавающей точкой float 4 байта 4 байта
double 8 байт 8 байт
long double 8 байт 8, 12 или 16 байт

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

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

double d ( 5.0 ) ; // 5.0 - это тип данных с плавающей точкой (по умолчанию double) float f ( 5.0f ) ; // 5.0 - это тип данных с плавающей точкой ("f" от "float")

Обратите внимание, литералы типа с плавающей точкой по умолчанию относятся к типу double. f в конце числа означает тип float.

Экспоненциальная запись

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

Рассмотрим массу Земли. В десятичной системе счисления она представлена как 5973600000000000000000000 кг . Согласитесь, очень большое число (даже слишком большое, чтобы поместиться в целочисленную переменную размером 8 байт). Это число даже трудно читать (там 19 или 20 нулей?). Но используя экспоненциальную запись, массу Земли можно представить, как 5.9736 × 10 24 кг (что гораздо легче воспринимается, согласитесь). Еще одним преимуществом экспоненциальной записи является сравнение двух очень больших или очень маленьких чисел — для этого достаточно просто сравнить их экспоненты.

В языке C++ буква е / Е означает, что число 10 нужно возвести в степень, которая следует за этой буквой. Например, 1.2 × 10 4 эквивалентно 1.2e4 , значение 5.9736 × 10 24 еще можно записать как 5.9736e24 .

Для чисел меньше единицы экспонент может быть отрицательным. Например, 5e-2 эквивалентно 5 * 10 -2 , что, в свою очередь, означает 5 / 10 2 или 0.05 . Масса электрона равна 9.1093822e-31 кг .

На практике экспоненциальная запись может использоваться в операциях присваивания следующим образом:

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