без потерь преобразование float в строку и обратно: возможно ли это? - PullRequest
4 голосов
/ 24 января 2012

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

Можно ли представить любое числовое (т. Е. Исключая специальные значения, например, NaN) значение с плавающей запятой или двойное в виде десятичной строки, такой, чтопреобразование этой строки обратно в число с плавающей запятой / double всегда будет давать именно исходное число?

Если нет, какой алгоритм подскажет, будет ли данное число испытывать ошибку преобразования?

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

Всегда ли необходимо вносить преднамеренные ошибки в десятичное представление, чтобы обмануть функцию atof (или другую), чтобы получить точное исходное число, или будет наивным, не-truncating toString функция будет адекватной (при условии точного преобразованиявообще возможно)?

Ответы [ 3 ]

7 голосов
/ 24 января 2012

Согласно этой странице :

На самом деле, стандарт IEEE754-1985 говорит, что 17 десятичных цифр достаточно во всех случаях. Тем не менее, кажется, что стандарт немного неясно, должны ли соответствующие реализации гарантировать без потерь преобразование при использовании 17 цифр.

Сохранение double в виде десятичной строки с не менее 17 цифрами (правильно округленными) гарантирует, что оно может быть преобразовано обратно в двоичный файл double без потери данных.

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


Я не уверен в минимальном отсчете для одинарной точности. Но я подозреваю, что это будет 8 или 9 цифр.

0 голосов
/ 10 мая 2013

В Java можно преобразовать double из / в строку, создав промежуточный объект BigDecimal:

double doubleValue = ...;

// From double to string
String valueOfDoubleAsString = new BigDecimal(doubleValue).toString();
// And back
double doubleValueFromString = new BigDecimal(valueOfDoubleAsString).doubleValue();

// doubleValue == doubleValueFromString

В этом методе нет языковых проблем. Однако специальные двойные значения (Infinite, NaN), конечно, не будут работать.

0 голосов
/ 24 января 2012

Учитывая, что формат IEEE может представлять только конечное число (двоичных) цифр и, следовательно, иметь минимальную точность (см. Epsilon), вам потребуется только конечное количество (десятичных) цифр. Конечно, предпочтительно, если реализация (strtod, snprintf) имеет поведение отображения идентификаторов между {всеми числами с плавающей запятой} и набором {одного десятичного представления для каждого числа с плавающей запятой}.

...