Это не так просто, как вы думаете. Все это сводится к представительности.
Рассмотрим простой пример 0.1
. Это значение точно не представлено в double
. Это связано с тем, что double
является двоичным, а не десятичным Представление.
значение А double
хранится в виде s*2^e
, где s
и e
являются мантисса и экспоненты, соответственно, оба целые числа.
Назад к 0.1
. Это значение не может быть точно представлено как двоичное значение с плавающей запятой. Никакой комбинации значимости и экспоненты не существует, которые ее представляют. Вместо этого будет использоваться closest representable value:
0.10000 00000 00000 00555 11151 23125 78270 21181 58340 45410 15625
Если это приходит в шок, я предлагаю следующие ссылки:
Итак, что делать? Очевидным вариантом является переход на десятичное, а не двоичное представление. В Delphi, который обычно означает использование типа Currency
. В зависимости от вашего приложения, которое может быть хорошим выбором, или это может быть ужасным выбором.Например, если вы хотите эффективно выполнять научные или инженерные расчеты, то десятичный тип не подходит.
Другой вариант - посмотреть, как это работает с Python. Функция repr
означает, где это возможно, чтобы получить строку со свойством, которое eval(repr(x)) == x
. В старых версиях Python repr
производились очень длинные строки формы 1.1000000000000001
, когда на самом деле 1.1
было бы достаточно. Python adopted an algorithm, который находит кратчайшее десятичное выражение, представляющее значение с плавающей запятой. Вы могли бы применить тот же подход. Проблема в том, что алгоритм очень сложный.
Вы хотите удалить нули, если они присутствуют в конце строки? –
Да, я бы хотел –