Как хранится плавающая запятая?Когда это имеет значение?

StackOverflow https://stackoverflow.com/questions/56947

  •  09-06-2019
  •  | 
  •  

Вопрос

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

Как хранятся числа с плавающей запятой?

Существует ли общий стандарт для разных размеров?

На какие ошибки мне следует обратить внимание, если я использую числа с плавающей запятой?

Совместимы ли они с разными языками (т. е. какие преобразования мне нужно выполнить, чтобы отправить число с плавающей запятой из программы Python в программу C через TCP/IP)?

-Адам

Это было полезно?

Решение

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

Вот некоторые распространенные ошибки:

  • Самым большим является то, что вы почти никогда не захотите сравнивать два числа с плавающей запятой на предмет равенства (или неравенства).Вместо этого вы захотите использовать сравнения «больше/меньше».
  • Чем больше операций вы выполняете с числом с плавающей запятой, тем более существенными могут стать ошибки округления.
  • Точность ограничена размером дроби, поэтому вы не сможете правильно складывать числа, разделенные несколькими порядками.(Например, вы не сможете добавить 1E-30 к 1E30.)

Другие советы

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

Стандарт ИЭЭЭ 754.

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

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

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

В C++ хорошее эмпирическое правило состоит в том, что число с плавающей запятой дает 7 цифр точности, а двойное — 15.Кроме того, если вам интересно узнать, как проверить равенство, вы можете посмотреть этот ветка вопросов.

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

Правильный.

Как хранятся числа с плавающей запятой?Существует ли общий стандарт для разных размеров?

Как уже упоминались другие плакаты, почти исключительно IEEE754 и его преемник IEEE754R.Погуглив, вы получите тысячи объяснений вместе с битовыми шаблонами и их объяснениями.Если у вас все еще есть проблемы с его получением, есть два распространенных формата FP:IBM и DEC-VAX.Для некоторых эзотерических машин и компиляторов (Blitzbasic, Turbopascal) есть некоторые нечетные форматы.

На какие ошибки мне следует обратить внимание, если я использую числа с плавающей запятой?Совместимы ли они с перекрестным языком (то есть с какими конверсиями мне нужно иметь дело, чтобы отправить номер плавающей запятой из программы Python в программу C по TCP/IP)?

Практически нет, они межъязыковы.

Очень редкие странности:

  • IEEE754 определяет sNaN (сигнальные NaN) и qNaN (тихие NaN).Первые вызывают ловушку, которая заставляет процессор вызывать подпрограмму-обработчик, если она загружена.Последние этого не делают.Поскольку разработчики языка ненавидели возможность того, что sNaN прерывают их рабочий процесс, а их поддержка требует поддержки подпрограмм-обработчиков, sNaN почти всегда автоматически преобразуются в qNaN.Поэтому не полагайтесь на необработанное преобразование 1:1.Но опять же:Это очень редко и происходит только в том случае, если присутствуют NAN.

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

Да, есть Стандарт IEEE для двоичной арифметики с плавающей запятой (IEEE 754)

При хранении в двоичном формате число делится на три части: знак, показатель степени и дробь.

Этот статья под названием «Числа с плавающей запятой по стандарту IEEE 754».Честно говоря, я не совсем уверен, что понимаю ваш вопрос, поэтому не уверен, что это будет полезно, но надеюсь, что так и будет.

Если вас действительно беспокоят ошибки округления с плавающей запятой, большинство языков предлагают типы данных, которые не имеют ошибок с плавающей запятой.SQL Server имеет типы данных Decimal и Money..Net имеет тип данных Decimal.Они не имеют бесконечной точности, как BigDecimal в Java, но они точны вплоть до количества десятичных знаков, для которых они определены.Таким образом, вам не нужно беспокоиться о том, что введенное вами долларовое значение в размере 4,58 доллара будет сохранено в виде значения с плавающей запятой 4,579999999999997.

Что я помню, так это то, что 32-битное число с плавающей запятой хранится с использованием 24 битов для фактического числа, а оставшиеся 8 бит используются как степень 10, определяя, где находится десятичная точка.

Хотя я немного заржавел в этой теме...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top