Что такое значение numeric_limits <double>:: digits10

Каково точное значение numeric_limits:: digits10? Некоторые другие связанные вопросы в stackoverflow заставляли меня думать, что это максимальная точность двойника, но

  • Следующий прототип начинает работать (sucess is true), когда точность больше, чем 17 (== 2 + numeric_limits:: digits10)
  • С STLPort, readDouble == бесконечность в конце; с microsoft STL, readDouble == 0.0.
  • Имеет ли этот прототип какой-либо смысл:)?

Вот прототип:

#include <float.h>
#include <limits>
#include <math.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
int main(int argc, const char* argv[]) {
  std::ostringstream os;
  //int digit10=std::numeric_limits<double>::digits10; // ==15
  //int digit=std::numeric_limits<double>::digits; // ==53
  os << std::setprecision(17);
  os << DBL_MAX;
  std::cout << os.str();
  std::stringbuf sb(os.str());
  std::istream is(&sb);
  double readDouble=0.0;
  is >> readDouble;
  bool success = fabs(DBL_MAX-readDouble)<0.1;
}

Ответы

Ответ 1

numeric_limits::digits10 - это число десятичных цифр, которое можно удерживать без потерь.

Например numeric_limits<unsigned char>::digits10 равно 2. Это означает, что unsigned char может содержать 0..99 без потерь. Если было 3, оно могло содержать 0..999, но, как мы все знаем, оно может содержать только 0..255.

На этой странице руководства приведен пример чисел с плавающей запятой, который (когда сокращен) показывает, что

cout << numeric_limits<float>::digits10 <<endl;
float f = (float)99999999; // 8 digits
cout.precision ( 10 );
cout << "The float is; " << f << endl;

печатает

6
The float is; 100000000

Ответ 2

numeric_limits:: digits10 указывает количество десятичных цифр слева от десятичной точки, которое вы можете представить без потери точности. Каждый тип будет иметь различное количество отображаемых десятичных значений.

Ответ 3

"53" - это ширина бита significand, которую поддерживает ваш тип (double). "15" - это число десятичных цифр, которое можно безопасно представить с такой точностью.

Ответ 4

См. этот очень читаемый документ: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2005.pdf

Хотя DBL_MAX (= std:: numeric_limits:: digits10 = 15 цифр) - это минимальное гарантированное количество цифр для double, значение DBL_MAXDIG10 (= 17 цифр), предлагаемое в документе, имеет полезные свойства:

  • Как минимальное количество цифр, необходимых для того, чтобы выжить в обратном направлении в форме строки и обратно и получить в конце тот же самый двойной символ.

  • Как минимальное количество цифр, необходимых для преобразования двойного  к строковой форме и показывать разные строки каждый раз, когда вы получаете (A!= B) в коде.  С 16 или менее цифрами вы можете получить парные разряды, не равные по коду,  но когда они преобразуются в строчную форму, они одинаковы  (что даст случай, когда они отличаются друг от друга по сравнению с кодом,  но файл журнала будет показывать их как идентичные - очень запутывающие и трудно отлаживаемые!)

Когда вы сравниваете значения (например, просматривая их вручную, используя два файла журнала), мы должны помнить, что цифры 1-15 ВСЕГДА действительны, но различия в 16-й и 17-й цифрах МОГУТ быть нежелательными.

Ответ 5

digits10 предназначен для преобразования: строка → double → строка
max_digits10 предназначен для преобразования: double → string → double

В вашей программе вы используете преобразование (double → string → double). Вы должны использовать max_digits10 вместо digits10.


Подробнее о digits10 и max_digits10 вы можете прочитать: