Ieee 754-1985 определяет четыре формата представления чисел с плавающей запятой:
§3. Основные понятия в представлении чисел с плавающей точкой.
3.1 Представление числа в нормализованном экспоненциальном виде.
Возьмем, к примеру, десятичное число 155,625 Представим это число в нормализованном экспоненциальном виде : 1,55625∙10 +2 =1,55625∙exp10 +2 Число 1,55625∙exp10 +2 состоит из двух частей: мантиссы M=1.55625 и экспоненты exp10=+2 Если мантисса находится в диапазоне 1<=M<10, то число считается нормализованным. Экспонента представлена основанием системы исчисления (в данном случае 10) и порядком (в данном случае +2). Порядок экспоненты может иметь отрицательное значение, например число 0,0155625=1,55625∙exp10 -2 .
3.2 Представление числа в денормализованном экспоненциальном виде.
Возьмем, к примеру, десятичное число 155,625 Представим это число в денормализованном экспоненциальном виде : 0,155625∙10 +3 =0,155625∙exp10 +3 Число 0,155625∙exp10 +3 состоит из двух частей: мантиссы M=0,155625 и экспоненты exp10=+3 Если мантисса находится в диапазоне 0,1<=M<1, то число считается денормализованным. Экспонента представлена основанием системы исчисления (в данном случае 10) и порядком (в данном случае +3). Порядок экспоненты может иметь отрицательное значение, например число 0,0155625=0,155625∙exp10 -3 .
3.3 Преобразование десятичного числа в двоичное число с плавающей точкой.
Наша задача сводится к представлению десятичного числа с плавающей точкой, в двоичное число с плавающей точкой в экспоненциальном нормализованном виде. Для этого разложим заданное число по двоичным разрядам:
155,625 = 1∙2 7 +0∙2 6 +0∙2 5 +1∙2 4 +1∙2 3 +0∙2 2 +1∙2 1 +1∙2 0 +1∙2 -1 +0∙2 -2 +1∙2 -3 155,625 =128 + 0 + 0 + 16 + 8 + 0 + 2 + 1 + 0,5 + 0 + 0,125 155,62510 = 10011011,1012 — число в десятичной и в двоичной системе с плавающей точкой Приведем полученное число к нормализованному виду в десятичной и двоичной системе: 1,55625∙exp10 +2 = 1,0011011101∙exp2 +111
В результате мы получили основные составляющие экспоненциального нормализованного двоичного числа: Мантиссу M=1,0011011101 Экспоненту exp2= +111
§4. Описание преобразования чисел по стандарту ieee 754.
4.1 Преобразование двоичного нормализованного числа в 32 битный формат ieee 754
Основное применение в технике и программирование получили форматы 32 и 64 бита. Например, в VB используют типы данных single (32 бита) и double (64 бита). В Си аналогично используют float (32 бита) и double (64 бит) Рассмотрим преобразование двоичного числа 10011011,101 в формат single-precision (32 бита) стандарта IEEE 754. Остальные форматы представления чисел в IEEE 754 являются увеличенной копией single-precision.
Чтобы представить число в формате single-precision IEEE 754 необходимо привести его к двоичному нормализованному виду. В §3 мы проделали это преобразование над числом 155,625. Теперь рассмотрим, как двоичное нормализованное число преобразуется к 32 битному формату IEEE 754.
Описание преобразования в 32 битный формат IEEE 754:
Число может быть + или — . Поэтому отводится 1 бит для обозначения знака числа: 0-положительное 1-отрицательное Этот самый старший бит в 32 битной последовательности .
Далее пойдут биты экспоненты, для этого выделяют 1 байт (8 бит). Экспонента может быть, как и число, со знаком + или -. Для определения знака экспоненты, чтобы не вводить ещё один бит знака, добавляют смещение к экспоненте в половину байта +127(0111 1111). То есть, если наша экспоната = +7 (+111 в двоичной), то смещенная экспонента = 7+127=134. А если бы, наша экспонента была -7 , то смещенная экспонета=127-7 =120. Смещенную экспоненту записывают в отведенные 8 бит. При этом, когда нам будет нужно получить экспоненту двоичного числа, мы просто отнимем 127 от этого байта.
Оставшиеся 23 бита отводят для мантиссы. Но, у нормализованной двоичной мантиссы первый бит всегда равен 1, так как число лежит в диапазоне 1<=M<2. Нет смыла, записывать единицу в отведенные 23 бита, поэтому в отведенные 23 бита записывают остаток от мантиссы.
В таблице представлено десятичное число 155,625 в 32-х битном формате IEEE754:
IEEE-754 Floating Point Converter
This page allows you to convert between the decimal representation of numbers (like «1.02») and the binary format used by all modern CPUs (IEEE 754 floating point).
| Sign | Exponent | Mantissa | |
| Value: | 0 | 2 0 | 0 |
| Encoded as: | 0 | 0 | 0 |
| Binary: |
Update
There has been an update in the way the number is displayed. Previous version would give you the represented value as a possibly rounded decimal number and the same number with the increased precision of a 64-bit double precision float. Now the original number is shown (either as the number that was entered, or as a possibly rounded decimal string) as well as the actual full precision decimal number that the float value is representing. Entering «0.1» is — as always — a nice example to see this behaviour. The difference between both values is shown as well, so you can easier tell the difference between what you entered and what you get in IEEE-754.
This webpage is a tool to understand IEEE-754 floating point numbers. This is the format in which almost all CPUs represent non-integer numbers. As this format is using base-2, there can be surprising differences in what numbers can be represented easily in decimal and which numbers can be represented in IEEE-754. As an example, try «0.1». The conversion is limited to 32-bit single precision numbers, while the IEEE-754-Standard contains formats with increased precision.
Usage:
You can either convert a number by choosing its binary representation in the button-bar, the other fields will be updated immediately. Or you can enter a binary number, a hexnumber or the decimal representation into the corresponding textfield and press return to update the other fields. To make it easier to spot eventual rounding errors, the selected float number is displayed after conversion to double precision.
Special Values:
You can enter the words «Infinity», «-Infinity» or «NaN» to get the corresponding special values for IEEE-754. Please note there are two kinds of zero: +0 and -0.
Conversion:
The value of a IEEE-754 number is computed as:
sign 2 exponent mantissa
The sign is stored in bit 32. The exponent can be computed from bits 24-31 by subtracting 127. The mantissa (also known as significand or fraction) is stored in bits 1-23. An invisible leading bit (i.e. it is not actually stored) with value 1.0 is placed in front, then bit 23 has a value of 1/2, bit 22 has value 1/4 etc. As a result, the mantissa has a value between 1.0 and 2. If the exponent reaches -127 (binary 00000000), the leading 1 is no longer used to enable gradual underflow.
Underflow:
If the exponent has minimum value (all zero), special rules for denormalized values are followed. The exponent value is set to 2 -126 and the «invisible» leading bit for the mantissa is no longer used.
The range of the mantissa is now [0:1).
Note: The converter used to show denormalized exponents as 2 -127 and a denormalized mantissa range [0:2). This is effectively identical to the values above, with a factor of two shifted between exponent and mantissa. However this confused people and was therefore changed (2015-09-26).
Rounding errors:
Not every decimal number can be expressed exactly as a floating point number. This can be seen when entering «0.1» and examining its binary representation which is either slightly smaller or larger, depending on the last bit.
Other representations:
The hex representation is just the integer value of the bitstring printed as hex. Don’t confuse this with true hexadecimal floating point values in the style of 0xab.12ef.
FAQ (Frequently Asked Questions):
Can you send me the source code? I need to convert format x to format y.:
This source code for this converter doesn’t contain any low level conversion routines. The conversion between a floating point number (i.e. a 32 bit area in memory) and the bit representation isn’t actually a conversion, but just a reinterpretation of the same data in memory. This can be easily done with typecasts in C/C++ or with some bitfiddling via java.lang.Float.floatToIntBits in Java. The conversion between a string containing the textual form of a floating point number (e.g. «3.14159», a string of 7 characters) and a 32 bit floating point number is also performed by library routines. If you need to write such a routine yourself, you should have a look at the sourecode of a standard C library (e.g. GNU libc, uclibc or the FreeBSD C library — please have a look at the licenses before copying the code) — be aware, these conversions can be complicated.
Can you add support for 64-bit float/16-bit float/non-IEEE 754 float?.:
This page relies on existing conversion routines, so formats not usually supported in standard libraries cannot be supported with reasonable effort. Double-precision (64-bit) floats would work, but this too is some work to support alongside single precision floats. As the primary purpose of this site is to support people learning about these formats, supporting other formats is not really a priority.
I’ve converted a number to floating point by hand/some other method, and I get a different result. Your converter is wrong!
Possible, but unlikely. The conversion routines are pretty accurate (see above). Until now, checking the results always proved the other conversion less accurate. First, consider what «correct» means in this context — unless the conversion has no rounding error, there are two reasonable results, one slightly smaller the entered value and one slightly bigger. The best result is usually the one closer to the value that was entered, so you should check for that. Please check the actual represented value (second text line) and compare the difference to the expected decimal value while toggling the last bits.
Note: If you find any problems, please report them here.
Преобразование дробного числа к двоичной системе счисления
Как преобразовать дробное десятичное число в двоичную систему счисления?
math.modf вариант: 0.510 = 0.12
Если у вас на входе число типа float, а на выходе вы хотите получить это число в двоичной системе (основание 2) как строку, то можно использовать math.modf() функцию, чтобы разбить число на целую и дробную части и вызвать float.as_integer_ratio() метод, чтобы представить дробь в виде отношения целых чисел, затем числитель в двоичной системе напечатать, с помощью b формата. Знаменатель является степенью двойки и определяет ширину дробной части в двоичной системе:
float.hex вариант в научной нотации: 0.510 = 0b1.0p-1
Чтобы получить строку в научной нотации (целая часть либо ровно 0 либо 1), то относительно лёгкий способ это злоупотребить шестнадцатеричным представлением:
math.frexp вариант
float уже хранится в двоичном представлении в компьютере. Можно использовать math.frexp(f) , чтобы разложить число с плавающей точкой на составляющие f = m * 2**e :
Все примеры в ответе точное представление получают, неточные вычисления не используются.
Разбираемся в числах с плавающей точкой (часть 0)
Здравствуйте, хабровчане. Я давно увлекаюсь темой регистров с плавающей точкой. Меня всегда волновало то, как происходит вывод на экран и т.д. Помню, давным-давно в универе реализовывал свой класс чисел с плавающей точкой, состоящих из 512 бит. Единственное, что я не мог никак реализовать — это вывод на экран.
Как только у меня появилось свободное время, я взялся за старое. Завел себе тетрадку и пошло-поехало. Хотелось додуматься до всего самому, лишь иногда заглядывая в стандарт IEEE 754.
И вот что из всего этого вышло. Интересующихся прошу под кат.
Чтобы освоить эту статью, надо знать следующее: что такое бит, двоичная система, арифметика на уровне знания отрицательных степеней. В статье не будут затронуты инженерные подробности реализации на уровне процессора а также нормализованные и денормализованные числа. Больший упор сделан на перевод числа в двоичную форму и наоборот, а также объяснение того, как вообще хранятся числа с плавающей точкой в виде битов.
Числа с плавающей точкой — очень мощный инструмент, которым надо уметь правильно пользоваться. Они не столь банальны, как целочисленные регистры, но и не столь сложны, если в них грамотно и потихоньку вникнуть.
В сегодняшней статье для примера я буду использовать 32-битные регистры. Числа с двойной точностью (64-битные) работают абсолютно по той же логике.
Сначала поговорим о том, как хранятся числа с плавающей точкой. Старший 31 бит у нас знаковый. Единичка значит, что число отрицательное, а ноль, соответственно наоборот. Далее идут 8 бит экспоненты. Эти 8 битов представляют из себя обычное беззнаковое число. И в самом конце идут 23 бита мантиссы. Для удобства будем обозначать знак как S, экспоненту как E, а мантиссу, как ни странно, M.
Получаем общую формулу
У мантиссы принято считать один неявный единичный бит. То есть мантисса будет представлять из себя 24 бита, но так как старший 23-й бит всегда единица, то его можно не записывать. Таким образом это «ограничение» будет давать нам единственность представления любого числа.
Мантисса из себя представляет обычное двоичное число, но в отличие от целых чисел, старший бит это 2^0 степени и далее по убыванию степеней. Вот тут и пригождается экспонента. В зависимости от ее значения, степень двойки старшего бита увеличивается либо уменьшается. Вот и вся гениальность этой задумки.
Давайте попробуем показать это на наглядном примере:
Представим число 3.625 в двоичном виде. Поначалу разобьем это число на степени двойки.
Степень старшей двойки равна единице. E – 127 = 1. E = 128.
0 1000000 11010000000000000000000
Вот и все наше число.
Попробуем также и в обратную сторону. Пусть у нас есть 32 бита, произвольные 32 бита.
0 10000100 (1)11011100101000000000000
В скобочках указан тот самый неявный старший бит.
Сначала вычислим экспоненту. E = 132. Соответственно степень старшей двойки будет равна 5. Итого имеем следующее число:
Нетрудно догадаться, что мы можем хранить всего лишь диапазон из 24-х степеней двойки. Соответственно, если два числа отличаются в экспоненте на больше чем 24, то при сложении число остается равным большему среди них.
Для удобной конвертации я накидал небольшую программу на языке C.
Шагом сетки является минимальная разницу между двумя соседними числами с плавающей точкой. Если представить последовательность битов такого числа как обычное целое число, то соседнее число с плавающей точкой будет отличаться в битах как целое число на единицу.
Можно выразиться иначе. Два соседних числа с плавающей точкой будут отличаться на 2 ^ (E — 127 — 23). То есть на разницу, равную значению младшего бита.
В качестве доказательства можете поменять main в коде и скомпилировать еще раз.
Думаю на сегодня можно закругляться, а то получается слишком длинно. В следующий раз буду писать о сложении чисел с плавающей точкой и потере точности при округлении.