Подтвердить что ты не робот

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

так почему в некотором значении это правильно, но иногда это неправильно?

пожалуйста, просветите меня. спасибо

4b9b3361

Ответ 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 не могут быть представлены, поэтому у вас есть что-то немного больше или немного меньше.

И, конечно, приведенные выше комментарии применяются ко всем другим значения, которые вы указали.