Setprecision сбивает с толку
Я просто хочу спросить о setprecision, потому что я немного смущен.
здесь код:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double rate = x;
cout << fixed << setprecision(2) << rate;
}
где x = следующее:
левая часть уравнения - это значения x.
1.105 = 1.10 должно быть 1.11
1.115 = 1.11 должно быть 1.12
1,125 = 1,12 должно быть 1,13
1.135 = 1.14, что верно
1.145 = 1.15 также верно
но если x:
2.115 = 2.12, что верно
2.125 = 2.12 должно быть 2.13
так почему в некотором значении это правильно, но иногда это неправильно?
пожалуйста, просветите меня. спасибо
Ответы
Ответ 1
Нет причин ожидать, что любая из констант в вашем сообщении может быть представлена точно с использованием системы с плавающей запятой. Как следствие, точные половинки, которые у вас есть, могут быть не более точными половинами после их хранения в переменной double
(независимо от того, как iostreams предназначены для округления таких чисел.)
Следующий код иллюстрирует мою точку зрения:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double rate = 1.115;
cout << fixed << setprecision(20) << rate;
}
Вывод:
1.11499999999999999112
Я бы порекомендовал взглянуть на FAQ.
Ответ 2
Некоторые из напечатанных вами номеров не могут быть представлены как число с плавающей запятой и могут быть на самом деле ниже или выше, чем вы думаете, непосредственно влияя на округление.
Так как вы пытаетесь отформатировать номер с плавающей запятой до фиксированной точки, считаете ли вы фактически ИСПОЛЬЗОВАНИЕ номера фиксированной точки (int/long scaled, скажем, 1000 в зависимости от ваших потребностей), который имеет свой собственный оператор вставки? Тогда вы всегда будете получать точный показ и округление без необходимости полагаться на setprecision
с каким-либо конкретным поведением (я не мог быстро найти соответствующий раздел преобразования в стандарте).
Ответ 3
Почему вы говорите, что 1.105 должно быть 1.11? В стандарте С++ говорится
ничего об этом, но режим округления по умолчанию на большинстве
обычные машины (Intel, Sparc и т.д.) округлены до четности, поэтому 1.105
должно быть 1.10. В общем, когда точный результат точно
между двумя представляемыми значениями, правило округляется до
один с наименьшей значащей цифрой.
Я также задаюсь вопросом, где вы получаете эти значения. В обычном
машины, 1.105 не могут быть представлены, поэтому у вас есть что-то
немного больше или немного меньше.
И, конечно, приведенные выше комментарии применяются ко всем другим
значения, которые вы указали.