Предположим, у меня есть

int i=25;
double j=(double)i;

Есть ли шанс, что j будет иметь значения 24.9999999..upto_allowed или 25.00000000..._upto_allowed_minus_one_and_then_1. Я помню, как где-то читал такие вещи, но не мог правильно вспомнить.

Другими словами:

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

6
sjsam 20 Апр 2016 в 08:06

3 ответа

Лучший ответ

Для небольших чисел, таких как 25, у вас все хорошо. Для очень больших (абсолютных) значений int в архитектуре, где int - 64-битное (имеющее значение, не представимое в 53-битном) или больше, вы потеряете точность.

Число с плавающей запятой двойной точности имеет точность 53 бита, из которых самый старший бит ( неявно) обычно 1.

На платформах, где представление с плавающей запятой не соответствует стандарту IEEE-754, ответ может быть немного другим. Подробнее см. В главе 5.2.4.2.2 спецификаций C99 / C11

5
Mohit Jain 20 Апр 2016 в 17:07

IEEE-754 double имеет значительную точность 53 бита. Это означает, что он может хранить все целые числа со знаком в диапазоне 2 ^ 53 и -2 ^ 53.

IEEE 754 Floating Point

Поскольку int обычно имеет 32 бита на большинстве компиляторов / архитектур, double обычно может обрабатывать int.

2
Mateen Ulhaq 20 Апр 2016 в 19:21

Ответ @Mohit Jain хорош для практического программирования.

Согласно спецификации C, DBL_DIG или FLT_RADIX/DBL_MANT_DIG и INT_MAX/INT_MIN являются важными значениями.

DBL_DIG в максимальном количестве десятичных цифр, которое может иметь число, которое при преобразовании в double и обратно обязательно будет иметь такое же значение. Это не менее 10. Таким образом, целое число, например 9 999 999 999, безусловно, может быть преобразовано в double и обратно без потери точности. Возможные более высокие значения также могут успешно возвращаться.

Настоящая проблема двустороннего обмена начинается с целочисленных значений, превышающих +/-power(FLT_RADIX, DBL_MANT_DIG). FLT_RADIX - это основание с плавающей запятой (и в подавляющем большинстве случаев это 2), а DBL_MANT_DIG - это "количество базовых - FLT_RADIX цифр в значении с плавающей запятой", например {{ X5}} с IEEE-754 binary64.

Конечно, int имеет диапазон [INT_MIN ... INT_MAX]. Диапазон должен быть не менее [-32767 ... + 32,767].

Когда математически power(FLT_RADIX, DBL_MANT_DIG) >= INT_MAX нет проблем с преобразованием. Это относится ко всем совместимым компиляторам C.

0
Community 23 Май 2017 в 10:28