Приведение из uint64_t в double приводит к неверным значениям - PullRequest
1 голос
/ 07 мая 2020

При преобразовании большого uint64_t значения в double . Результаты не такие, как ожидалось. Почему это так и есть ли способ решить эту проблему. Я использую g cc 8.3.0

int main
{
   uint64_t var64 = 844421103279395000;

   printf("var64     = %llu\n", var64 );

   double varDouble = (double)var64;

   printf("varDouble = %lf\n", varDouble );

   return 0;
}

Результат выглядит следующим образом:

var64     = 844421103279395000
varDouble = 844421103279394940.000000

1 Ответ

4 голосов
/ 07 мая 2020

A double, при условии, что он использует представление двойной точности IEE754, может содержать только 53 бита точности. A uint64_t использует все 64 бита как биты значения, что означает, что есть некоторые значения, которые могут быть сохранены точно в uint64_t, но не могут быть сохранены точно в double.

В вашем примере 844421103279395000 имеет шестнадцатеричное представление 0‭BB7 FC84 FDCF D0B8‬. Ближайшее значение с точностью 53 бита - 0‭BB7 FC84 FDCF D080, что составляет 844421103279394944 в десятичном формате. Это значение близко к отображаемому, но разница, вероятно, связана с тем, как printf обрабатывает ввод значащих цифр.

...