Кто-нибудь может объяснить представление поплавка в памяти?


20

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

Может ли кто-нибудь помочь мне в понимании how float values are stored in the memory.

Я сомневаюсь, что здесь значения с плавающей запятой содержат ' .'( for example 3.45), как '.'будет отображаться в памяти?

Может кто-нибудь, пожалуйста, уточнить меня с диаграммой?


21
Как насчет наименее ожидаемого источника, Википедии? en.wikipedia.org/wiki/Floating_point#Internal_representation
9000

4
И вы можете добавить основную статью: IEEE с плавающей запятой
mouviciel

4
Если вы похожи на меня, и вам нравится учиться, играя с вещами, вводя входные данные и получая выходные данные и т. Д., Проверьте этот сайт: binaryconvert.com/convert_double.html
KChaloux

Существует множество форматов с плавающей точкой, все разные. IEEE с плавающей точкой является наиболее распространенным в настоящее время, но это не единственный. Когда я учился, мне пришлось изучать формат CDC 6600 с плавающей запятой, и он имел некоторые преимущества перед IEEE, самое большое из которых - 48 бит мантиссы для одинарной точности. IEEE ограничен примерно 24 битами мантиссы для одинарной точности, поэтому каждый вводный класс численных методов в эти дни говорит ученикам: «Всегда используйте двойное число, а не число с плавающей запятой».
Джон Р. Штром

Ответы:


44

Десятичная точка явно нигде не хранится; это проблема отображения.

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

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

    0,7853975 * 2 2

0.7853975 - это значение , aka мантисса; это часть номера, содержащая значащие цифры. Это значение умножается на основание 2, возведенное в степень 2, чтобы получить 3,14159.

Числа с плавающей запятой кодируются путем хранения значений и экспоненты (вместе со знаковым битом).

Типичная 32-битная компоновка выглядит примерно так:

 3 32222222 22211111111110000000000
 1 09876543 21098765432109876543210
+-+--------+-----------------------+
| |        |                       |
+-+--------+-----------------------+
 ^    ^                ^
 |    |                |
 |    |                +-- significand 
 |    |
 |    +------------------- exponent 
 |
 +------------------------ sign bit

Как и целочисленные типы со знаком, старший бит указывает знак; 0 обозначает положительное значение, 1 обозначает отрицательное.

Следующие 8 бит используются для показателя степени. Экспоненты могут быть положительными или отрицательными, но вместо резервирования другого знакового бита они кодируются так, что 10000000 представляет 0, поэтому 00000000 представляет -128, а 11111111 представляет 127.

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

    01101 = 0 * 2 -1 + 1 * 2 -2 + 1 * 2 -3 + 0 * 2 -4 + 1 * 2 -5 
          = 0,25 + 0,125 + 0,03125 
          = 0,40625

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

Таким образом, наше значение 3.14159 будет представлено как что-то вроде

    0 10000010 11001001000011111100111
    ^ ^ ^
    | | |
    | | + --- значимое = 0,7853975 ...
    | |
    | + ------------------- экспонента = 2 (130 - 128)
    |
    + ------------------------- знак = 0 (положительный)

    значение = -1 (знак) * 2 (показатель степени) * (значение и)
    значение = -1 0 * 2 2 * 0,7853975 ...
    значение = 3.14159 ...

Теперь, что вы заметите, если сложите все биты в значении и что они не составляют 0,7853975; они на самом деле выходят до 0,78539747. Недостаточно битов для точного хранения значения ; мы можем хранить только приближение. Количество бит в значении и определяет точность или сколько значащих цифр вы можете сохранить. 23 бита дают нам примерно 6 десятичных цифр точности. 64-битные типы с плавающей запятой предлагают достаточное количество бит в значении и дают примерно 12-15 цифр точности. Но имейте в виду, что есть значения, которые не могут быть представлены точно, независимо от того, какмного битов вы используете. Так же, как значения, такие как 1/3, не могут быть представлены конечным числом десятичных цифр, значения, подобные 1/10, не могут быть представлены конечным числом битов. Поскольку значения являются приблизительными, вычисления с ними также являются приблизительными, и ошибки округления накапливаются.

Количество бит в показателе степени определяет диапазон (минимальное и максимальное значения, которые вы можете представить). Но по мере продвижения к вашим минимальным и максимальным значениям размер разрыва между представленными значениями увеличивается. То есть, если вы не можете точно представить значения между 0,785397 и 0,785398, то вы не можете точно представить значения между 7,85397 и 7,85398, либо значения от 78,5397 до 78,5398, либо значения между 785397.0 и 785398.0. Будьте осторожны при умножении очень больших (по величине) чисел на очень маленькие числа.


«но вместо того, чтобы зарезервировать другой знаковый бит» Вы описываете точное поведение целого числа со знаком.
Саймон

6

.Не хранится на всех. Во-первых, вы должны понимать инженерную нотацию, которая имеет коэффициент фиксированной точности и целочисленный показатель степени: 11,0 · 10 0 = 1.0E0, 2 - это 2.0E010 1.0E1и т. Д. Это допускает очень короткую запись больших чисел. Один миллиард есть 1.0E9. Коэффициент перед Eобычно нотирован как фиксированной точностью номер: 1.00000E9. Результатом этого является то, что число один миллиард и один = 1 000 000 001 и один миллиард одинаковы в этой записи, когда точность недостаточно велика. Также обратите внимание, что фактор никогда не нуждается в ведущем нуле. Вместо этого показатель степени может быть уменьшен до тех пор, пока это не так.

В памяти число с плавающей запятой представляется аналогично: один бит имеет знак, некоторые биты составляют коэффициент как число с фиксированной точностью («мантисса»), остальные биты образуют показатель степени. Существенные отличия от инженерной нотации base-10 заключаются в том, что теперь у экспоненты есть база 2. Точный размер каждой части зависит от того, какой именно стандарт с плавающей запятой вы используете.


3
Это «Научная запись». «Инженерная нотация» - это когда показатель степени ограничен числом, кратным 3.
Клемент Дж.

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

1
@delnan: Если это помогает, каждый бит в мантиссе - это половина старшего бита. Таким образом, числа с плавающей запятой могут хранить суммы отрицательных степеней двух: 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 и т. Д. До предела мантиссы , Так что эпсилон в 32-х битах floatэто 2^-22 * exponentили около 1/4194304.
Greyfade
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.