Почему такое поведение происходит? что десятичное число после 6-го места увеличивается до следующего в двойном размере, но не увеличивается при преобразовании в целое число.
Это вызывает проблемы при преобразовании в int, потому что, несмотря на печать 3, d1 по-прежнему преобразуется в 2 при преобразовании в целое число, а не в 3
double d1 = 2.999999; //6 digits after decimal
double d2 = 2.777777;
double d3 = 2.77777; //5 digits after decimal
double d4 = 2.99999;
cout<<d1<<endl; //gives 3
cout<<(int)d1<<endl; //still gives 2 not 3
cout<<d2<<endl; //gives 2.777778
cout<<d3<<endl; //gives 2.77777 as expected
cout<<d4<<endl; //gives 2.99999 as expected
Я предполагаю, что он должен что-то делать с компиляторами или точностью, но я не уверен в этом неожиданном поведении. Пожалуйста, помогите
Никакого увеличения здесь не происходит. Когда значение отображается как 3
, это не означает, что значение изменилось. Это именно то, что было определено программой, как правильный способ отображения значения.
Поведение по умолчанию функции std::cout
заключается в том, что она будет печатать двойные числа с точностью до 6 цифр. Это не меняет значение d1
, но округляет его при отображении.
Отвечает ли это на ваш вопрос? Как с помощью cout вывести двойное значение с полной точностью?
Я думаю, что основная проблема здесь заключается в том, что когда вы печатаете число с плавающей запятой, по умолчанию оно округляется до определенного количества значащих цифр (что, кстати, не то же самое, что «цифры после запятой»). Если вы не измените его, количество значащих цифр по умолчанию равно 6. Вот почему 2,999999 (с семью значащими цифрами) было округлено, а правильно округленное значение равно 3. Однако, когда вы приводите это число к (int)
, это преобразование просто выдает уберите дробную часть, дав вам 2.
Также вы должны знать, что все эти разговоры о «значащих цифрах» или «знаках после запятой» применимы только тогда, когда мы печатаем числа в десятичном формате для чтения людьми! Внутренне числа с плавающей запятой обычно представляются в двоичном формате с основанием 2 и на самом деле вообще не содержат десятичных цифр.
Это потому, что точность по умолчанию для cout
равна 6.
Компилятор достаточно точно распознает все значения, но вывод округляется до 6 знаков после запятой.
Если вам нужен точный результат, вы можете изменить код следующим образом:
cout << setprecision(7);
double d1 = 2.999999; //6 digits after decimal
double d2 = 2.777777;
double d3 = 2.77777; //5 digits after decimal
double d4 = 2.99999;
cout<<d1<<endl; //gives 2.999999
cout<<(int)d1<<endl; //still gives 2 not 3
cout<<d2<<endl; //gives 2.777777
cout<<d3<<endl; //gives 2.77777 as expected
cout<<d4<<endl; //gives 2.99999 as expected
Кроме того, вы не получите «точный» результат, установив точность на 7; вы получаете ожидаемый результат, но 2.777777
не может быть точно представлено в форматах с плавающей запятой IEEE, поэтому вы получаете самое близкое приближение к сохраненному значению.
это не имеет ничего общего с С++. В С++ нет определенных форматов с плавающей запятой, и реализация может использовать IEEE-754 или что-то еще. Но округление при печати точно указано, а точность тоже 6 по умолчанию, поэтому очевидно печатание 2.77777 сильно отличается от 2.777777