ZaLinux.ru

Почему в C++ для double в числе только 5 цифр после запятой

В языке C++ при определении переменных необходимо указать их тип, причём в дальнейшем тип менять нельзя.

Для числовых переменных распространёнными типами являются int, short, long, float и double.

К примеру, переменная с типом данных float — это число с плавающей точкой, для хранения которого используется 4 байта, а это 6-9 значимых цифр, обычно 7.

А переменная с типом данных double — это число с плавающей точкой, для хранения которого используется 8 байт, а это примерно 15-18 значимых цифр, обычно 16.

Зная это, рассмотрим следующий простейший код — для его выполнения, сохраните код в файл test.cpp:

#include <iostream>
using namespace std;

int main () {
   // определение чисел:
   short  s;
   int    i;
   long   l;
   float  f;
   double d;

   // присвоение значений числам;
   s = 10;
   i = 1000;
   l = 1000000;
   f = 230.4732;
   d = 30949.12345678;

   // печать чисел;
   cout << "short  s :" << s << endl;
   cout << "int    i :" << i << endl;
   cout << "long   l :" << l << endl;
   cout << "float  f :" << f << endl;
   cout << "double d :" << d << endl;

   return 0;
}

Теперь скомпилируйте его:

g++ test.cpp

И выполните:

./a.out

Результат выполнения очень необычен:

short  s :10
int    i :1000
long   l :1000000
float  f :230.473
double d :30949.1

Число 230.4732 обрезано до 230.473 — потерян одна цифра после запятой. А в числе типа double, значение которого 30949.12345678, обрезалось до 30949.1 — то есть вместо предполагаемых 15-18 значимых цифр получено только 6…

Отсюда возникает вопрос, почему в числе типа double можно использовать только 6 значимых цифр?

На самом деле, число double d содержит все цифры после запятой, которые присвоены этой переменной — всё дело в том, как выполняется проверка числа. У метода cout имеются свои настройки по умолчанию для вывода и форматирования чисел — если в числе больше 6 разрядов, то обрезаются цифры после запятой, если до запятой также больше 6 цифр, то используется научная запись числа, например 1.23457e+14.

Такое поведение по умолчанию cout можно исправить. Для этого, во-первых, необходимо добавить новый заголовок #include <iomanip>.

Во-вторых нужно использовать std::setprecision(n), где n — это новая величина точности.

При использовании в выражении out << setprecision(n) или in >> setprecision(n) устанавливает для параметра точности потока out или in значение ровное n.

Отредактирует код нашей программы:

#include <iostream>
#include <iomanip>
using namespace std;

int main () {
   // определение чисел:
   short  s;
   int    i;
   long   l;
   float  f;
   double d;

   // присвоение значений числам;
   s = 10;
   i = 1000;
   l = 1000000;
   f = 230.4732;
   d = 30949.12345678;

   // печать чисел;
   cout << "short  s :" << s << endl;
   cout << "int    i :" << i << endl;
   cout << "long   l :" << l << endl;
   cout << setprecision(7) << "float  f :" << f << endl;
   cout << setprecision(13) << "double d :" << d << endl;

   return 0;
}

Заново скомпилируем и выполним его. Результат:

short  s :10
int    i :1000
long   l :1000000
float  f :230.4732
double d :30949.12345678

Именно этот результат мы и ожидали:

Отметим ещё раз — в самой программе используются все возможные знаки и разряды чисел, цифры обрезались в момент вывода.

Смотрите также онлайн учебник «Основы С++».

Рекомендуемые статьи:

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *