Почему бы просто не хранить числа с плавающей точкой как целые числа

414
Lance Pollard

Есть несколько случаев поплавков, о которых я думаю

// small 1.1 // medium 1.12 // large 1.123 // extra large 1.12398491859158 // ridiculously large 1.198591851958995815915891581958958198595891958199159859 // large to the point of not really being useful except in rare cases like calculating an infinite series 1.198591851958995815915891581958958198595891958199159859198591851958995815915891581958958198595891958199159859198591851958995815915891581958958198595891958199159859198591851958995815915891581958958198595891958199159859 

Кажется, вы можете представить эти числа как 2 целых числа:

1 and 1 1 and 12 1 and 123 etc. 

Итак, первые 3 будут 2 8-битными числами, скажем, 2 байта.

Вы также можете представлять большие числа с целыми числами, которые разбиты на маленькие куски, которые объединяются вместе. Так 198591851958995815915891581958958198595891958199159859может быть ... ну я не знаю, как это будет работать. Это похоже на концепцию BigNumber, с которой я не слишком знаком. Итак, я начинаю с простого понимания, почему числа с плавающей запятой не могут быть просто представлены как целые числа.

Интересно, можно ли это объяснить? Может быть, вы достигнете некоторого снижения производительности, а может быть, снижение производительности произойдет только в определенных случаях (например, анимация миллионов объектов в x / y-положении, например, с задержкой менее 16 мс). Я пока не вижу (а), как реализовать плавающие числа как целые числа каким-либо идеальным способом, или (б), как это сделать оптимально, поэтому я не уверен, стоит ли это вообще исследовать. Я не уверен, есть ли аппаратные причины, по которым один подход может быть лучше другого.

Причина, по которой меня это интересует, заключается в том, что мне было бы интересно представлять произвольные числа с плавающей точкой для математических целей, и в то же время обрабатывать обычные «маленькие» числа с плавающей точкой, такие как 1.1и 1.123, для анимации или других целей. И система будет просто иметь «числовой» тип, чтобы обрабатывать оба случая одинаково.

-3
Пожалуйста, измените вопрос, чтобы ограничить его конкретной проблемой с достаточным количеством деталей, чтобы найти адекватный ответ. Ramhound 6 лет назад 0
Вам следует иметь в виду, что действительные числа не обязательно имеют конечное представление (например, пи или е), и даже рациональные числа могут иметь или не иметь конечное представление, если вы решили представлять дроби в определенной базе (например, 1/9). Таким образом, вам придется иметь дело с потерей точности (ни у одного компьютера нет бесконечной памяти). Важный вопрос заключается в том, как бороться с * эффективно *. Ваш выбор представительства, хотя, безусловно, возможен в принципе, этого не сделает. dirkt 6 лет назад 0
Вы не можете гарантировать, что результат деления или умножения любых случайных «простых чисел» не приведет к сложным числам с плавающей точкой. Mokubai 6 лет назад 0

3 ответа на вопрос

2
RalfFriedl

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

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

2
phuclv

Хранение поплавков, как вы сказали, не сработает. Как вы будете представлять 1.01, 1.00001 ...? Для большинства практических целей сохранение значения и целого в целом было бы гораздо лучше, поскольку вы можете выполнять математику напрямую, не разбивая операции на целые и дробные части.

Например, 2 числа с плавающей запятой x × B n и y × B m в базе B будут добавлены как (x × B m-n + y) × B m и умножены на x × y × B m + n . Не нужно заботиться о том, где находится точка радиуса, и не нужно сдвигать цифры между двумя отдельными целыми и дробными частями

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

На самом деле этого doubleуже достаточно в большинстве случаев, поэтому вряд ли какая-либо аппаратная архитектура поддерживает 128-разрядное плавание

Сколько десятичных чисел Пи нам действительно нужно?

2
Ramhound

Кажется, вы можете представить эти числа как 2 целых числа:

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

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

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

Конечные числа, которые можно описать тремя целыми числами: s = знак (ноль или один), c = значимое и (или коэффициент), имеющий не более p цифр, когда записывается в основание b (т. Е. Целое число в диапазоне от 0 до bp − 1) и q = показатель степени такой, что emin ≤ q + p − 1 ≤ emax. Числовое значение такого конечного числа равно (−1) s × c × bq. [A] Кроме того, существует два нулевых значения, называемых нулями со знаком: знаковый бит указывает, равен ли ноль +0 (положительный ноль) или - 0 (отрицательный ноль).

Источник

Причина, по которой я заинтересован, заключается в том, что мне было бы интересно представлять произвольные числа с плавающей точкой для математических целей, и в то же время обрабатывать обычные «маленькие» числа с плавающей точкой, такие как 1.1 и 1.123, для анимации или других целей. И система будет просто иметь «числовой» тип, чтобы обрабатывать оба случая одинаково.

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

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

Я еще раз повторю, что то, что вы описываете, будет нарушать стандарт IEEE. Это также было бы неэффективно. Чтобы понять причину, большинство языков программирования не пытаются определить тип с плавающей запятой с точностью до одной цифры, вам нужно понимать компьютерные регистры. Размер компьютерного регистра является конкретным, что означает, что 32-разрядный регистр будет хранить 32-разрядные, даже если они содержат все 0, поэтому с плавающей запятой с точностью до одной цифры все равно будет использоваться 32-разрядный регистр.

Другими словами, все ваши примеры уже обработаны уже существующим форматом с плавающей запятой одинарной точности.

enter image description here

Источник

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

@LancePollard - я обновил ответ, но причина, по которой ваш мыслительный процесс имеет недостатки, заключается в том, что вы пытаетесь определить формат для обработки чего-то, что уже обрабатывается существующим форматом. Если вы хотите узнать больше, вам придется больше исследовать и иметь некоторое базовое представление о числах с плавающей запятой и о том, как они представлены в двоичном виде. Ramhound 6 лет назад 1
@LancePollard - по этой причине я ссылался на стандарт IEEE. Ramhound 6 лет назад 0

Похожие вопросы