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

Переменная с плавающей точкой с – Урок №33. Типы данных с плавающей точкой | Уроки С++

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

Стандарт IEEE 754-1985 определяет

  • Представление нормализованных положительные и отрицательные числа с плавающей точкой.

  • Представление нормализованных положительные и отрицательные числа с плавающей точкой.

  • Представлениенулевыхчисел,

  • Представление специальной величины — бесконечность (Infiniti),

  • Представление специальной величины «Не число» (NaN – No a Number),

IEEE 753-1985 определяет 4 формата представления чисел с плавающей запятой:

  • с одинарной точностью (single-precision) 32 бита,

  • с двойной точностью (double-precision) 64 бита,

  • с одинарной расширенной точностью (single-extended precision) >=43 бит (редко используемый),

  • с двойной расширенной точностью (double-extended precision) >= 79 бит (обычно используют 80 бит).

Основное применение в технике и программирование получили форматы 32 и 64 бита. Например, в С# используют типы данных single и double.

Основные понятия в представлении чисел с плавающей точкой.

Возьмем, к примеру, десятичное число 155.625. Представим это число в нормализованном экспоненциальном виде: 1.55625*102=1.55625e+2.

Число 1.55625e+2 состоит из двух частей: мантиссы M=1.55625 и экспоненты e =+2.

Нормализованные числа Если мантисса находится в диапазоне 1<=M<2 то число считается нормализованным.

Денормализованные числа. Это числа, мантиссы которых лежат в диапазоне 0.1 <= M <1 Денормализованные числа находятся ближе к нулю, чем нормализованные. Денормализованные числа как бы разбивают минимальный разряд нормализованного числа на некоторое подмножество. Сделано так потому, что в технической практике чаще встречаются величины близкие к нулю.

Экспонента представлена основанием системы исчисления (в данном случае 10) и порядком (в данном случае +2). Порядок экспоненты может иметь отрицательное значение, например число 0,0155625=1,55625e-2.

Формальное представление нормализованных чисел в формате IEEE 754.

  • S — бит знака числа (0 — положительное число; 1 — отрицательное число).

  • E — смещенная экспонента (смещение для устранения знака порядка). Порядок = E — 2(b-1) + 1 , где E- экспонента двоичного нормализованного числа с плавающей точкой, 2(b-1)-1 — смещение экспоненты.

  • M — остаток мантиссы двоичного нормализованного числа с плавающей точкой (Первый бит мантиссы всегда 1, поэтому он скрывается).

Формула вычисления десятичных чисел с плавающей точкой из чисел, представленных в стандарте IEEE754:

Формула расчета нормализованных чисел:

Формула расчета денормализованных чисел:

Формат числа одинарной точности (single-precision) 32 бита

Формат числа двойной точности (double-precision) 64 бита

Исключения чисел формата IEEE754. Если применить формулу нормализованных чисел для вычисления минимального и максимального числа в формате single, представленного в IEEE754, то получим следующие результаты:

  • 00 00 00 00 hex= 5,87747175411144e-39 (минимальное положительное).

  • 80 00 00 00 hex=-5,87747175411144e-39 (минимальное отрицательное).

  • 7f ff ff ff hex= 6,80564693277058e+38 (максимальное положительное).

  • ff ff ff ff hex=-6,80564693277058e+38 (максимальное отрицательное).

Отсюда видно, что невозможнопредставить число нуль в заданном формате.

Поэтому из стандарта сделаны исключения, и формула не применяется в следующих случаях:

  • Числа, которые выходят за границы диапазона представления чисел считаются бесконечными. Число IEEE754=7F 80 00 00hex считается числом +∞. Число IEEE754=FF 80 00 00hex считается числом -∞.

  • NAN (No a Number) – не число.Числа IEEE754=FF (1xxx)X XX XXhex не считается числами, кроме +∞. Числа IEEE754=7F (1xxx)X XX XXhex не считается числами, кроме -∞. Числа, представленные в битах с 0…22, могут быть любыми кроме 0.

Полный диапазон чисел в формате 32 бит по стандарту IEEE754:

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

Тип

Диапазон

Точность

float

±1,5e−45 … ±3,4e38

7 знаков

double

±5,0e−324 … ±1,7e308

15 -16 знаков

studfiles.net

Типы данных с плавающей точкой. Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

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

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

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

Числа с плавающей точкой могут быть использованы для представления значений, больших, чем это возможно для масштабируемых целых. Например, тип FLOAT может содержать числа с абсолютным значением не более 3.4Е38 (т. е. 34, за которым следует 37 нулей) и не менее 1.1Е-38 (37 нулей, 11 и затем десятичная точка).

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

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

Например, FLOAT может содержать число 1000000000 (1 000 000 000 или 10(^9^)). «Контейнер» FLOAT рассматривает данное число как 100000*Е4. (Это лишь иллюстрация — полное представление реализации чисел с плавающей точкой выходит за рамки настоящей книги и очень далеко от того, что узнал автор!). Если вы прибавите 1 к значению FLOAT, то будет проигнорирована информация в седьмом разряде, потому что она не является значимой для текущего значения числа и его точности. Если же вы прибавляете 10 000 — число, которое значимо для хранимого в типе FLOAT числа, — то результатом может быть 100001*Е4.

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

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

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

Для сравнений проверяйте значения с плавающей точкой в предложении BETWEEN с подходящим диапазоном вместо того, чтобы выполнять точную проверку. Тот же совет применим и для сравнения с нулем — выберите подходящий диапазон значений и запишите проверку данных между нулем и близким к нулю значением или между двумя подходящими значениями, близкими к нулю[23].

В базе данных диалекта 1 необходимость хранения значений числовых данных, имеющих больший диапазон, чем предоставляет 32-битовое целое, может быть решена выбором типа DOUBLE PRECISION. Ограничения диалекта 1 также требуют использования чисел с плавающей точкой для всех действительных чисел, если к базе данных предполагается доступ из встроенного приложения (ESQL).

Firebird предоставляет два приближенных числовых типа данных с плавающей точкой (FLOAT и DOUBLE PRECISION), отличающиеся только размером точности.

FLOAT является 32-битовым типом данных с плавающей точкой с приблизительно 7 цифрами точности — для надежности предполагайте 6 цифр. Число с 10 цифрами 25.33333312, добавленное в столбец FLOAT, сохраняется как 25.33333. Диапазон чисел от -3.402 x 10(^38^) до 3.402 x 10(^38^). Наименьшее положительное число, которое может быть сохранено, 1.175 * 10(^-38^).

Поделитесь на страничке

Следующая глава >

it.wikireading.ru

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

Поиск Лекций

Простые типы данных

К простым типам относят: одиночные символы, любые числовые переменные и пр.

Код

Char ch;// один 8-битный символ (в разных компиляторах может быть unsigned или signed)

Unsigned char uch;// гарантированно беззнаковая 8-битная переменная; байт проще говоря

Signed char sch;// гарантировано знаковая 8-битная переменная; минус один бит на знак

Int i;// целочисленная переменная со знаком

Unsigned int ui;// целочисленная переменная без знака

Float fl;// число с плавающей точкой

Сложные типы данных.

К сложным типам данных относят для Си — структуры, объединения и массивы; для Си++ — тоже + классы. Сложные типы можно также назвать составными, т.к. они в конечном итоге всё равно содержат в себе простые (сложный тип = набор простых). Важно понять, что процессор не умеет работать со сложными типами. Он не может понять, что такое std::string или char. Для него это — набор простых типов. Программист так же никогда не работает со сложными типами напрямую — он работает только с указателями на сложные типы. Что это такое разберём дальше.

Типы данных в Си++

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

1) внутреннее представление данных в памяти компьютера;

2) множество значений, которые могут принимать величины этого типа;

3) операции и функции, которые можно применять к данным этого типа.

В зависимости от требований задания программист выбирает тип для объектов программы. Типы Си++ можно разделить на простые и составные. К простым типам отно- сят типы, которые характеризуются одним значением. В Си++ определено 6 простых ти- пов данных:

int (целый)

char (символьный)

wchar_t (расширенный символьный)

bool (логический)

float(вещественный)

double (вещественный с двойной точностью)

Существует 4 спецификатора типа, уточняющих внутреннее представление и диапазон стандартных типов

short (короткий)

long (длинный)

signed (знаковый)

unsigned (беззнаковый)

Тип int

Значениями этого типа являются целые числа. Размер типа int не определяется стандартом, а зависит от компьютера и компилято- ра. Для 16-разрядного процессора под него отводится 2 байта, для 32-разрядного – 4 байта.

Если перед int стоит спецификатор short, то под число отводится 2 байта, а если спецификатор long, то 4 байта. От количества отводимой под объект памяти зависит мно- жество допустимых значений, которые может принимать объект:

short int — занимает 2 байта, следовательно, имеет диапазон –32768 ..+32767;

long int – занимает 4 байта, следовательно, имеет диапазон –2 147 483 648..+2 147 483 647

Тип int совпадает с типом short int на 16-разрядных ПК и с типом long int на 32- разрядных ПК.

Модификаторы signed и unsigned также влияют на множество допустимых значе- ний, которые может принимать объект:

unsigned short int — занимает 2 байта, следовательно, имеет диапазон 0 ..65536;

unsigned long int – занимает 4 байта, следовательно, имеет диапазон 0..+4 294 967 295.

Тип char

Значениями этого типа являются элементы конечного упорядоченного множества символов. Каждому символу ставится в соответствие число, которое называется кодом символа. Под величину символьного типа отводится 1 байт. Тип char может использовать- ся со спецификаторами signed и unsigned. В данных типа signed char можно хранить зна- чения в диапазоне от –128 до 127. При использовании типа unsigned char значения могут находиться в диапазоне от 0 до 255. Для кодировки используется код ASCII(American Standard Code foe International Interchange). Символы с кодами от 0 до 31 относятся к слу- жебным и имеют самостоятельное значение только в операторах ввода-вывода.

Величины типа char также применяются для хранения чисел из указанных диапазо- нов.

 

Тип wchar_t

Предназначен для работы с набором символов, для кодировки которых недостаточ- но 1 байта, например Unicode. Размер этого типа, как правило, соответствует типу short.

Строковые константы такого типа записываются с префиксом L: L“String #1”.2.2.4. Тип bool Тип bool называется логическим. Его величины могут принимать значения true и false. Внутренняя форма представления false – 0, любое другое значение интерпретируется как true.

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

Внутреннее представление вещественного числа состоит из 2 частей: мантиссы и порядка. В IBM-совместимых ПК величины типа float занимают 4 байта, из которых один разряд отводится под знак мантиссы, 8 разрядов под порядок и 24 – под мантиссу.

Величины типы double занимают 8 байтов, под порядок и мантиссу отводятся 11 и 52 разряда соответственно. Длина мантиссы определяет точность числа, а длина порядка его диапазон.

Если перед именем типа double стоит спецификатор long, то под величину отводит- ся байтов.

Тип void

К основным типам также относится тип void Множество значений этого типа – пу- сто

Рекомендуемые страницы:

Поиск по сайту

poisk-ru.ru

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

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

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

-1.56Е+12    2.87е-3

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

3.14159

    .2

    4е16

    .8Е-5

    100.

Использовать пробелы при записи констант запрещается

1.56Е+ 12 — НЕПРАВИЛЬНО

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

some = 4.0*2.0;

     В этом случае константы 4.0 и 2.0 размещаются в памяти как данные типа double, т. е. для каждой из них (обычно) отводится 64 бит. Их произведение (равное 8) вычисляется с помощью операции умножения, выполняемой с двойной точностью, и только после этого производится усечение результата до нормального размера, соответствующего типу float. Все это обеспечивает максимальную точность ваших вычислений.

Поделитесь на страничке

Следующая глава >

it.wikireading.ru

Стандарт IEEE754-2008 представления чисел с плавающей запятой

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

         Действительное число может быть записано несколькими способами. Рассмотрим различные виды (формы) записи. Число 36,6 мы можем записать как 0,366∙102. Различие форматов записи в десятичной системе счисления наглядно можно увидеть в продуктовом магазине. Где-то на одной пачке товара может быть написано 1 кг (считай 1∙103 г), а на другой 1000 г, а где-то будет 0,5 кг. А измерь мы вес какого-нибудь товара, например, в тройских унциях, явно придётся округлять значения или отбрасывать разряды, оставляя лишь n знаков после запятой.

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

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

         В первом случае мы можем все вычисления делать с типом float (либо другим). Во-втором случае рассмотрите фрагмент кода, который PHP-интерпретатор правильно распознает, преобразует форматы, а потом правильно посчитает и выведет сумму.

<?php
$a='1';
$b=0.5;
$c=4;
$d=$a+$b+$c;
echo $d;
?>
А для третьего случая приведём код на С с явным указанием типов:
int a=1;
float b=0.5;

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

         Переход от десятичной системы счисления к двоичной рассматривать не будем, так как эти вещи рассматриваются в школьном курсе информатики. Если забыли, см. «Cхема Горнера и перевод из одной позиционной системы в другую» [26, § 14, стр. 37–39].

2.1.4.3.1. Терминология

         Если не брать в рассмотрение представление нуля, бесконечности и прочих исключений как чисел с плавающей запятой, то можно практически считать синонимами термины «число с плавающей запятой» и «число, записанное в экспоненциальной форме». В связи с чем числа с плавающей запятой в общем случае можно представить в экспоненциальном виде: ν= F =M⋅qp , где M – мантисса, q – основание системы счисления, а p – показатель степени или порядок числа ν (или F).

2.1.4.3.2. Алгоритм преобразования


2.1.4.4. «10 формул!»

47

Практическая проверка правильности вычислений показала, что предыдущие преобразования верны. Если проводимые вычисления не показались вам сложными и вы считаете, что уже умеете преобразовывать любые числа по формату IEE754, то спешим вас огорчить, рано радуетесь. Если бы мы говорили о формате хранения целых беззнаковых чисел, то можно было бы «остановиться», так как для них используется всего лишь одна формула преобразований. В случае же с действительными числами забежим вперёд и скажем, что таких формул будет 10! В примере выше мы использовали лишь одну, ниже разберём остальные. В этом, наверное, и кроется основная проблема изучения формата хранения чисел, когда обучаемыми рассматриваются лишь некоторые случаи преобразований, а все остальные уходят из рассмотрения.

Понять сказанное проще, проведя рассуждения «от обратного», а именно «от памяти к числу». Так как для хранения данных одной переменной типа float у нас задействовано 32 двоичных разряда, то максимальное число вариантов будет 232, начиная 32 «нулями» и заканчивая всеми «единицами». Записывать числа удобнее в более компактной шестнадцатеричной форме, где начало и конец будут 00 00 00 00 и FF FF FF FF. см. табл. 2.8a.

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

         Далее, если попытаться разместить более-менее адекватно все множества на числовой оси (как мы привыкли слева направо), то получится примерно следующая картинка, взятая из [17]. см. рис. 2.3.


Рассмотрим подробнее рис. 2.3. Над воображаемой осью координат «x» записаны значения ячеек памяти. Под осью записаны значения чисел, а цветом указаны «форму- лы», по которым можно осуществить преобразования, причём с целью упрощения и исходя из симметрии их число (как и цветов на рис., оттенков при чёрно-белом изда- нии) сокращено до пяти. «Пробежимся» по положительной части оси и разберём их.

2.1.4.5.1. Ноль (нуль)

48

«Ноль – он и в Африке ноль». Для представления нуля в памяти используется комбинация нулей во всех 32 разрядах. Согласитесь, что это тривиально и легко запомнить.

Фрагмент памяти ЭВМ, содержащий значения 00 00 00 0016 (следует учитывать, что реальная последовательность хранения зависит от архитектуры, см. стр. 36), будучи интерпретирован как число формата binary32 IEEE754-2008, считается числом «+0».

«+0»

Следует отметить, что если рассматривать «отрицательную область», то там тоже будет «свой» ноль.

«−0»

Из рисунков видно, что при шестнадцатеричной записи в памяти отображение «–0» будет как 80 00 00 00 (следует учитывать, что реальная последовательность хранения зависит от архитектуры и может быть обратной, см. стр. 36).

При кодировании целых чисел одним байтом от значения «−0» отказались в пользу ещё одного отрицательного числа, вот почему при 256 вариантах мы пользуемся не симметричным диапазоном [−127, +127], а асимметричным [−128, +127], как и [−32768, +32767] и т. д. Смею предположить, что «+0» и «−0», с точки зрения математики, если не рассматривать пределы справа и слева, есть одно и то же – «0», а в чём различие «+» и «−» – философский вопрос. Однако из факта существования двух нулей технически можно сделать интересные выводы, например для операции сравнения. Если ранее, при использовании целых чисел, из равенства «представления чисел в памяти ЭВМ» следовало и равенство самих чисел, то для типов с плавающей запятой одним сравнением уже не обойтись. Например, при сравнении фрагментов памяти 80 00 00 00 и 00 00 00 00, хранящих числа с плавающей запятой, побитно видно, что они различаются, а значит, можно ошибочно предположить, что числа, представленные данными записями, разные, по факту же мы понимаем, что числа равны.

Замечание, открытый вопрос

Почему комбинация 80 00 00 0016 не была использована для представления какого-нибудь ещё числа, как это было сделано с целыми типами?

Смеем предположить, что с целыми типами, при использовании 8 бит, «выигрыш» оказался существен, плюс несложность добавления числа «на край» отрицательных чисел подсказала простое решение, как использовать это значение. Целые типы с большим числом разрядов просто унаследовали данный подход. Что же касается чисел с плавающей запятой, видимо, даже при разработке стандарта IEEE754 сочли вклад 1/216 для формата Binary16 несущественным, не говоря уже о меньшем вкладе 1/232 для формата binary32 и т. д. Следует отметить, что в «блоке NaN», о котором написано ниже, заложено больше неиспользуемых значений.

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

2.1.4.5.2. Нормализованные числа

49


Ранее мы рассмотрели пример преобразования температуры t = 36,6 °C и определили как десятичное число 36,6 будет храниться в памяти ЭВМ. Фактически мы для этого использовали «нормализованный» формат хранения числа в памяти. Рассмотрим общую формулу преобразования и какие из неё следуют ограничения. Стандарт IEEE754 по этому поводу предлагает следующее хранение данных в памяти (см. рис. 2.4): Рисунок 2.4. Распределение битов в памяти ЭВМ для хранения чисел с плавающей запятой по стандарту IEEE754 где переменные берутся из таблицы 2.6, в зависимости от желаемой точности. Работа с первоисточниками есть основа знаний, но не всегда они удобны для восприятия рядовыми читателями, в связи с этим предлагаем обратиться к «адаптированным фрагментам» стандарта от Владимира Яшкардина в [17] и от Сергея Холодилова в [25], где указанные вопросы изложены намного лучше (недостаток – отличные обозначения), так как на ряду с наглядными картинками приводятся различные примеры.
Рисунок 2.5. Распределение битов памяти по формату IEEE754 при точности binary32 (w ≡ b = 8, t ≡ n = 23, k = 32) (верх – общая формула; низ – binary32) На рис. 2.5:
  • S – бит знака;
  • E – смещённый показатель степени двоичного числа;
  • T – остаток мантиссы двоичного нормализованного числа с плавающей запятой (в [17] и [25] обозначается через M, что вносит путаницу).

Дадим некоторые пояснения. Переход от смещённого показателя к реальному выполняется вычитанием смещения, которое равно (2(b − 1) − 1) ≡ (2(w−1) −1). То есть для расчётов реальная степень числа 2 вычисляется как хранимое значение минус смещение: E−(2(w−1)−1), для binary32 получится E−127.

         Дополнительная сложность для читателей (слушателей) в восприятии материала состоит в том, что через букву T обозначен остаток мантиссы, а не сама мантисса. Почему так оказывается удобнее, будет разъяснено позднее. Нормализация подразумевает, что для мантиссы будет выполняться следующее условие: 1 ≤ | Mреальная | 10 ≤ Mреальная 10 10. Запишем ограничения условий в двоичной системе счисления. Получим 12 ≤ Mреальная 2 2. Допишем не значащие (с точки зрения математики) нули для наглядности.

         Получим 1,00000000…2Mреальная 22, то есть Mреальная 2 есть число вида 1,xxxxxxxx…, где, как уже легко заметить, первая цифра в записи всегда равна 1.

         Если мы хотим записать в память t знаков дробной части числа 1,xxxxxxxx…, придётся вычесть из него единицу (какой смысл её хранить, занимая ячейку памяти, если она всегда равна 1?), после чего мы получим 0,xxxxxxxx…, далее следует «передвинуть» запятую на t разрядов вправо, что для двоичной системы равносильно умножению числа на 2t.          То есть общая формула преобразования будет T = (Mреальная−1)·2t, выразим из этого выражения Mреальная:          Сопоставив изложенное выше, получим общую формулу, связывающую представляемое число и хранимые в памяти ЭВМ данные: , (формула № 1) для формата binary32 из табл. 2.7 подставим следующие значения: w ≡ b = 8, t ≡ n = 23, k = 32, в результате чего получим:
         Замечание. В нормализованной форме записи невозможно записать 0. Так как запиши мы в представлении мантиссы нули – получим единицу, а запиши мы в степени число, дающее после вычитания смещения ноль – получим 20, что по определению есть 1, следовательно, формула № 1, где используется произведение этих чисел, даст в результате единицу, а не ноль. Если же мы вспомним, что договорились представлять ноль всеми нулями и запишем их в формулу № 1, то получим 5,87747175411144·10−39 – самое минимальное положительное число, представимое такой формулой. Заметим, что это число не может быть представлено форматом IEEE754 binary32, так как мало (совсем на «чуть-чуть» меньше того, что позволяет представить формат). Аналогично для числа со знаком «минус» −5,87747175411144·10−39. Фактически именно эти числа являются представлением «+0» и «−0» в модели IEEE754. Ну а то, что число 0 есть в памяти 00 00 00 0016, как мы договорились выше, есть красивое совпадение.

2.1.4.5.3. 2.1.4.4.3. Денормализованные числа

51


(англ. denormalized numbers, subnormal numbers)          Денормализованные числа – это числа, которые нельзя представить в нормализованной форме по формуле № 1. Попытаемся ответить на вопрос: «В чём преимущество денормализованных чисел?» Чтобы ответить на этот вопрос, разберёмся, чем они отличаются от нормализованных, тогда всё и встанет на свои места. Рассуждения ниже по большей части основаны на материале, взятом из [19], который был переработан и дополнен, устранены ошибки. Для упрощения изложения рассмотрим «игрушечный» формат «несуществующий binary5», в котором возможно не только представить, но и перебрать все 25 = 32 вариантов чисел для большей ясности.

         Из пяти битов записи «xyyzz» отведём один бит на кодирование знака (поле «S»), два бита на кодирование показателя степени (поле «Е»), два бита для хранения кода мантиссы (поле «T»). Для поля знака S имеем два варианта: «0» и «1». Пусть «0» кодирует знак «+», а «1» – знак «−». Представим параметры формата «несуществующий binary5» в табл. 2.9 на ряду со значениями существующего формата binary32 стандарта IEEE 754-2008.

Таблица 2.9. Параметры формата «несуществующий binary5»


         Поясним значение «emax» максимального показателя степени. На его кодирование отведено 2 бита, значит возможны варианты: «00», «01», «10», «11». Учитывая необходимость кодирования как положительных, так и отрицательных значений степени, ставим в соответствие этим вариантам: −1, 0, 1, 2 (таким образом, смещение «bias» равно 1). (Если вы не поняли, почему мы выбрали именно эти значения и сместили их таким образом, предложите свой вариант и поищите у него недостатки, нарисовав ось и разместив на ней получившиеся у вас числа.)          Так как нормализованная мантисса для двоичных чисел всегда имеет вид 1,xxxxxxxx2 (ноль мы не рассматриваем), то первый единичный бит можно в памяти не хранить (то есть он хранится «неявно» и, при необходимости выполнить вычисления, восстанавливается автоматически). Поэтому отведённые под мантиссу 2 бита мы будем использовать для хранения первых двух знаков после запятой, что позволит хранить в памяти ещё один бит дробной части мантиссы. Поэтому точность p в табл. 2.9 записана как три, так как 3 = 2 + 1.          В придуманном нами пятибитовом формате возможно представить 16 чисел со знаком «+» (см. табл. 2.10), размещение которых на числовой оси представлено на рис.2.6.

… подробнее см. в бумажном издании, либо по запросу на почту…

2.1.4.5.4. Бесконечность (∞)

57


Так как по формуле № 1 представить число «+∞» не представляется возможным, впрочем, как и 0, было предложено сделать исключение и ввести данное число в формат IEEE754 дополнительно. Если ноль представлялся всеми нулями, то логично было бы представить бесконечность единицами во всех разрядах (кроме знака). Однако так не поступили, возможно из-за потенциально сложных технических решений, предложив рассматривать числа с максимально возможной степенью отдельно. Так, числа, у которых по представлению рис. 2.6 в смещённом показателе степени окажутся все единицы, следует рассматривать отдельно, а наименьшее из этих чисел, согласно формуле № 1, то есть то, где все биты мантиссы будут равны нулю, следует считать числом «+∞». Для формата binary32 IEEE754 это будет число записанное в памяти как 7F 80 00 00 (следует учитывать, что реальная последовательность байтов зависит от архитектуры, см. стр. 36, аналогично и для −∞). «+∞» Фрагмент памяти, содержащий значения FF 80 00 00, будучи интерпретирован по формату binary32 IEEE754, будет считаться ЭВМ как −∞. «−∞» В рассмотренном примере выше число 410, записанное в памяти как 01100, можно было бы интерпретировать как +∞.

2.1.4.5.5. Не числа (NaN, Not a Number)

58

2.1.4.6. Интересные наблюдения

59

         Теперь, когда мы поверхностно ознакомились с форматом хранения действительных чисел приведём несколько интересных наблюдений и перейдём к экспериментам с целью проверки на практике полученных знаний.          было замечено в [19], одна из удивительных особенностей представления чи- сел в формате IEEE754 состоит в том, что порядок и мантисса расположены друг за другом таким образом, что вместе образуют последовательность целых чисел {n}, для которых выполняется: n F(n)          Как было замечено в [19], одна из удивительных особенностей представления чисел в формате IEEE754 состоит в том, что порядок и мантисса расположены друг за другом таким образом, что вместе образуют последовательность целых чисел {n}, для которых выполняется:          n F(n) где F(n) – число с плавающей запятой, образованное от целого n разбиением его битов на «смещённый порядок» и «часть битов мантиссы». Поэтому если взять положительное число с плавающей запятой, преобразовать его к целому, прибавить «1», мы получим следующее число, которое представимо в этой арифметике.

… подробнее см. в бумажном издании, либо по запросу на почту…


Приобрести учебник по «Информатике» в котором изложен данный материал можно в издательстве «ДМК-Пресс», в торгово-издательском холдинге «Планета Альянс», в интернет-магазине «Альт Линукс», в редакции и интернет-магазине журнала «Системный администратор», в г.Тула, а также в интернет магазинах и книжных магазинах вашего города.

learn2prog.ru

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

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

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

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

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

Нормальной формой числа с плавающей запятой называется такая форма, в которой мантисса (без учёта знака) находится на полуинтервале [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). Пара значений показателя зарезервирована для обеспечения возможности представления специальных чисел. К ним относятся значения бесконечность), получающихся в результате операций типа деления на ноль нуля, положительных и отрицательных чисел. Также сюда попадают денормализованные числа, у которых мантисса меньше единицы. В специализированных устройствах (например GPU) поддержка специальных чисел часто отсутствует. Существуют программные пакеты, в которых объём памяти выделенный под мантиссу и показатель задаётся программно, и ограничивается лишь объёмом доступной памяти ЭВМ.

dic.academic.ru

javascript — понимание переменных с плавающей запятой

Ok. Позвольте мне попытаться объяснить это.

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

Как вы знаете, в базовых 2 арифметических целых числах представлены степени 2, которые они содержат. Таким образом, 6 будет представлено как 4 + 2, т.е. в двоичном формате 110.

Чтобы понять, как представлены дробные числа, вам нужно подумать о том, как мы представляем дробные числа в нашей десятичной системе. Дробная часть чисел (например, 0.11) представлена ​​в виде кратных обратных степеней 10 (так как основание равно 10). Таким образом, 0.11 фактически составляет 1/10 + 1/100. Как вы понимаете, это недостаточно мощно, чтобы представлять все дробные числа в ограниченном количестве цифр. Например, 1/3 будет 0,333333…. в бесконечном порядке. Если бы у нас было всего 32 цифры пробела, чтобы записать число вниз, мы получим только приблизительное значение к исходному числу, 0.3333333333333333333333333333333333. Это число, например, дало бы 0.9999999999999999999999999999999999, если бы оно было умножено на 3, а не 1, как вы ожидали.

Ситуация аналогична в базе-2. Каждое дробное число будет представлено как кратность обратных степеней 2. Таким образом, 0,75 (в десятичной форме) (т.е. 3/4) будет представлено как 1/2 + 1/4, что будет означать 0.11 (в базе-2). Так же, как база 10 не может достаточно представить каждое дробное число конечным образом, base-2 не может представлять все дробные числа при ограниченном пространстве.

Теперь попробуйте представить 0.11 в базе-2; вы начинаете с 11/100 и пытаетесь найти обратную мощность 2, которая меньше этого числа. 1/2 не работает, 1/4 ни, ни 1/8. 1/16 подходит для счета, поэтому вы отмечаете 1 на 4-м месте после десятичной точки и вычитаете 1/16 из 11/100, Осталось 19/400. Теперь попробуйте найти следующую мощность 2, которая соответствует описанию. 1/32 кажется тем, что отметьте 5-е место после точки и вычтите 1/32 от 19/400, вы получите 13/800. Следующий — 1/64, и вы остаетесь с 1/1600, а следующая — на уровне 1/2048 и т.д. и т.д. Таким образом, мы получили до 0.00011100001, но он продолжается и продолжается; и вы увидите, что всегда остается остаток. Теперь я не прошел весь расчет, но после того, как вы поместили 32 бинарных цифры после точки, вы, вероятно, по-прежнему будете иметь некоторую долю слева (и это предполагает, что все 32 бита пространства расходуются, представляя десятичную часть, которой это не так). Таким образом, я уверен, что вы можете понять, что итоговое число может отличаться от его фактического значения на некоторую величину.

В вашем случае разница составляет 0,00000000000000001, что составляет 1/100000000000000000 = 1/10 ^ 17, и я уверен, что вы можете понять, почему у вас может быть это.

qaru.site

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

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