Почему Setprecision округляет по другому?
выводит разные результаты. Как это исправить? Какие еще есть варианты вывести определенное количество знаков после запятой?
Отслеживать
задан 22 фев 2023 в 9:02
53 4 4 бронзовых знака
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
setprecision не округляет числа, он устанавливает точность вывода чисел с плавающей точкой в поток вывода, т.е. количество знаков после десятичной точки. Округление чисел происходит в функциях round() , floor() .
Для того, чтобы правильно округлять числа при выводе, нужно использовать соответствующую функцию округления, например, round() , и задавать нужную точность вывода с помощью функции setprecision() . Если установленная точность не совпадает с фактическим числом знаков после десятичной точки, то результат округления может отличаться от ожидаемого. Например, если задать точность вывода в 1 знак после десятичной точки, то число 3.25 будет выведено как 3.2, а не как 3.3, как при использовании функции round() .
Отслеживать
ответ дан 22 фев 2023 в 9:24
1,231 1 1 золотой знак 4 4 серебряных знака 16 16 бронзовых знаков
Есть такой вот простой вариант, который не округляет вовсе ничего, просто пишет ровно столько знаков, сколько вы зададите вместо цифры «9»:
printf("%.9f", -3.25);
Вообще есть ещё вариант писать std::ceil и std::floor , в зависимости, куда вам надо округлить. std::setprecision округляет предыдущую цифру по последующей, насколько я понял по своим экспериментам. В документации не написана логика округления.
Если хотите вывести одну цифру после запятой — используйте printf(«%.1f», -3.25);
Можете допустим так же в строку перевести std::to_string(-3.25)
и потом её выводить до одного символа после запятой (или точки, по идеи там будет точка как разделитель).
Setprecision c что это



Скачай курс
в приложении
Перейти в приложение
Открыть мобильную версию сайта
© 2013 — 2023. Stepik
Наши условия использования и конфиденциальности

Public user contributions licensed under cc-wiki license with attribution required
Функции
Извлекает денежное значение из потока с помощью указанного формата и возвращает значение в параметре.
template T7 get_money(Money& amount, bool use_intl);
Параметры
amount
Извлеченное денежное значение.
use_intl
Если true , используется международный формат. Значение по умолчанию — false .
Замечания
Манипулятор возвращает объект, который при извлечении из потока str ведет себя как formatted input function , вызывающий функцию-член get для ограничения языкового стандарта money_get , связанного с str , с использованием use_intl для указания международного формата. Если успешно, вызов сохраняет в amount извлеченное денежное значение. Затем манипулятор возвращает str .
Money должен иметь тип long double или быть экземпляром basic_string с теми же параметрами элемента и признаков, что и str .
get_time
Извлекает значение времени из потока с помощью указанного формата. Возвращает значение в параметре в виде структуры времени.
template T10 get_time(struct tm *time_ptr, const Elem *time_format);
Параметры
time_ptr
Время в виде структуры времени.
time_format
Формат, используемый для получения значения времени.
Замечания
Манипулятор возвращает объект, который при извлечении из потока str ведет себя как formatted input function , вызывающий функцию-член get для ограничения языкового стандарта time_get , связанного с str , с использованием tptr для указания структуры времени и fmt для указания начала строки формата, завершающейся нулем. В случае успешного выполнения вызов хранит в структуре времени значения, связанные с полями извлеченного времени. Затем манипулятор возвращает str .
Пример
#include #include #include int main() < std::cout > std::get_time(&when, "%R"); if (!std::cin.fail()) < std::cout return (int)std::cin.fail(); >
put_money
Вставляет денежный объем с помощью указанного формата в поток.
template T8 put_money(const Money& amount, bool use_intl);
Параметры
amount
Денежная сумма для вставки в поток.
use_intl
true Если манипулятор должен использовать международный формат, false если он не должен.
Возвращаемое значение
Замечания
Манипулятор возвращает объект, который при вставке в поток str ведет себя как форматированная выходная функция, вызывающая функцию-член put для ограничения языкового стандарта money_put , связанного с str . При успешном выполнении вызов вставляет amount подходящий формат, используя use_intl для указания международного формата и str.fill() элемента заливки. Затем манипулятор возвращает str .
Money должен иметь тип long double или быть экземпляром basic_string с теми же параметрами элемента и признаков, что и str .
put_time
Записывает значение времени из структуры времени в поток с использованием указанного формата.
template T10 put_time(struct tm* time_ptr, const Elem* time_format);
Параметры
time_ptr
Значение времени для записи в поток в виде структуры времени.
time_format
Формат для записи значения времени.
Замечания
Манипулятор возвращает объект, который при вставке в поток str ведет себя как formatted output function . Функция вывода вызывает функцию-член put для ограничения языкового стандарта time_put , связанного с str . Выходная функция используется time_ptr для указания структуры времени и time_format указания начала строки формата, завершаемой значением NULL. В случае успешного выполнения вызов вставляет текст из строки формата и преобразованные значения из структуры времени. Затем манипулятор возвращает str .
quoted
(Новое в C++14) Манипулятор iostream , обеспечивающий удобный обход строк в потоки и из него с помощью >> операторов.
quoted(std::string str) // or wstring quoted(const char* str) //or wchar_t* quoted(std::string str, char delimiter, char escape) // or wide versions quoted(const char* str, char delimiter, char escape) // or wide versions
Параметры
str
, std::string char* строковый литерал или необработанный строковый литерал или широкая версия любого из них (например, std::wstring ). wchar_t*
delimiter
Указанный пользователем символ или двухбайтовый символ для использования в качестве разделителя для начала и конца строки.
escape
Указанный пользователем символ или двухбайтовый символ для использования в качестве escape-символа для escape-последовательностей в строке.
Замечания
Примеры
В этом примере показано, как использовать quoted с разделителем по умолчанию и escape-символ с помощью узких строк. Широкие строки также поддерживаются.
#include #include #include using namespace std; void show_quoted_v_nonquoted() < // Results are identical regardless of input string type: // string inserted < R"(This is a "sentence".)" >; // raw string literal // string inserted < "This is a \"sentence\"." >; // regular string literal const char* inserted = "This is a \"sentence\"."; // const char* stringstream ss, ss_quoted; string extracted, extracted_quoted; ss > extracted; ss_quoted >> quoted(extracted_quoted); cout int main(int argc, char* argv[]) < show_quoted_v_nonquoted(); // Keep console window open in debug mode. cout ; getline(cin, input); > /* Output: ss.str() is storing : This is a "sentence". ss_quoted.str() is storing: "This is a \"sentence\"." After round trip: Non-quoted : This Quoted : This is a "sentence". Press Enter to exit */
В следующем примере показано, как предоставить пользовательский разделитель или escape-символ:
#include #include #include using namespace std; void show_custom_delimiter() < string inserted< R"("This" "is" "a" "heavily-quoted" "sentence".)" >; // string inserted< "\"This\" \"is\" \"a\" \"heavily-quoted\" \"sentence\"" >; // const char* inserted< "\"This\" \"is\" \"a\" \"heavily-quoted\" \"sentence\"" >; stringstream ss, ss_quoted; string extracted; ss_quoted > quoted(extracted, '*'); cout ; ss >> extracted; cout void show_custom_escape() < string inserted< R"(\\root\trunk\branch\nest\egg\yolk)" >; // string inserted< "\\\\root\\trunk\\branch\\nest\\egg\\yolk" >; stringstream ss, ss_quoted, ss_quoted_custom; string extracted; // Use '"' as delimiter and '~' as escape character. ss_quoted_custom int main(int argc, char* argv[]) < cout ; getline(cin, input); > /* Output: Custom delimiter: ss_quoted.str() is storing: *"This" "is" "a" "heavily-quoted" "sentence".* ss.str() is storing : "This" "is" "a" "heavily-quoted" "sentence". After round trip: Quoted : "This" "is" "a" "heavily-quoted" "sentence". Non-quoted : "This" Custom escape character: ss_quoted_custom.str(): "\\root\trunk\branch\nest\egg\yolk" ss_quoted.str() : "\\\\root\\trunk\\branch\\nest\\egg\\yolk" ss.str() : \\root\trunk\branch\nest\egg\yolk Press Enter to exit */
resetiosflags
Удаляет указанные флаги.
T1 resetiosflags(ios_base::fmtflags mask);
Параметры
mask
Флажки, которые нужно очистить.
Возвращаемое значение
Манипулятор возвращает объект, который при извлечении из потока или вставке в поток str , вызовов str.setf(ios_base::fmtflags, mask) , а затем возвращает str , см setf . и fmtflags .
Пример
См. setw с примером использования resetiosflags .
setbase
Задает основание целых чисел.
T3 setbase(int base);
Параметры
base
Основание числа.
Возвращаемое значение
Манипулятор возвращает объект, который при извлечении из потока или вставке в поток str , вызовы str.setf(mask, ios_base::basefield) , а затем возвращается str , см. раздел ios_base::basefield . mask Здесь определяется следующим образом:
- Если base значение равно 8, то mask есть ios_base::oct .
- Если base значение равно 10, то маски . ios_base::dec
- Если base значение равно 16, то mask есть ios_base::hex .
- Если base имеется другое значение, маски — ios_base::fmtflags(0) «.
Пример
См. setw с примером использования setbase .
setfill
Задает символ, который будет использоваться для заполнения пробелов на экране с выравниванием по правому краю.
template T4 setfill(Elem Ch);
Параметры
Ch
Задает символ, который будет использоваться для заполнения пробелов при показе с выравниванием по правому краю.
Возвращаемое значение
Манипулятор шаблона возвращает объект, который при извлечении из потока или вставке в поток str , вызовов str.fill(Ch) , а затем возвращается str . Тип Elem должен совпадать с типом элемента для потока str .
Пример
См. setw с примером использования setfill .
setiosflags
Задает указанные флаги.
T2 setiosflags(ios_base::fmtflags mask);
Параметры
mask
Флажки, которые нужно установить.
Возвращаемое значение
Манипулятор возвращает объект, который при извлечении из потока или вставке в поток str , вызовы str.setf(mask) , а затем возвращается str , см. раздел setf .
Пример
См. setw с примером использования setiosflags .
setprecision
Задает точность для значений с плавающей запятой.
T5 setprecision(streamsize Prec);
Параметры
Prec
Точность для значений с плавающей запятой.
Возвращаемое значение
Манипулятор возвращает объект, который при извлечении из потока или вставке в поток str , вызовы str.precision(Prec) , а затем возвращается str , см. раздел precision .
Пример
См. setw с примером использования setprecision .
setw
Ширина поля отображения для следующего элемента в потоке.
T6 setw(streamsize Wide);
Параметры
Wide
Ширина поля отображения.
Возвращаемое значение
Манипулятор возвращает объект, который при извлечении из потока или вставке из нее str , вызывается str.width(Wide) , а затем возвращается str . Дополнительные сведения см. в разделе width .
Замечания
setw задает ширину только для следующего элемента в потоке и необходимо вставить перед каждым элементом, ширина которого требуется указать.
Пример
// iomanip_setw.cpp // compile with: /EHsc // Defines the entry point for the console application. // // Sample use of the following manipulators: // resetiosflags // setiosflags // setbase // setfill // setprecision // setw #include #include using namespace std; const double d1 = 1.23456789; const double d2 = 12.3456789; const double d3 = 123.456789; const double d4 = 1234.56789; const double d5 = 12345.6789; const long l1 = 16; const long l2 = 256; const long l3 = 1024; const long l4 = 4096; const long l5 = 65536; int base = 10; void DisplayDefault( ) < cout void DisplayWidth( int n ) < cout void DisplayLongs( ) < cout int main( int argc, char* argv[] )
default display d1 = 1.23457 d2 = 12.3457 d3 = 123.457 d4 = 1234.57 d5 = 12345.7 setprecision(3) default display d1 = 1.23 d2 = 12.3 d3 = 123 d4 = 1.23e+003 d5 = 1.23e+004 setprecision(12) default display d1 = 1.23456789 d2 = 12.3456789 d3 = 123.456789 d4 = 1234.56789 d5 = 12345.6789 setiosflags(4096) default display d1 = 1.234567890000e+000 d2 = 1.234567890000e+001 d3 = 1.234567890000e+002 d4 = 1.234567890000e+003 d5 = 1.234567890000e+004 resetiosflags(4096) default display d1 = 1.23456789 d2 = 12.3456789 d3 = 123.456789 d4 = 1234.56789 d5 = 12345.6789 setfill('S') fixed width display set to 15. d1 = SSSSS1.23456789 d2 = SSSSS12.3456789 d3 = SSSSS123.456789 d4 = SSSSS1234.56789 d5 = SSSSS12345.6789 default display d1 = 1.23456789 d2 = 12.3456789 d3 = 123.456789 d4 = 1234.56789 d5 = 12345.6789 setfill(' ') fixed width display set to 15. d1 = 1.23456789 d2 = 12.3456789 d3 = 123.456789 d4 = 1234.56789 d5 = 12345.6789 default display d1 = 1.23456789 d2 = 12.3456789 d3 = 123.456789 d4 = 1234.56789 d5 = 12345.6789 setprecision(8) fixed width display set to 10. d1 = 1.2345679 d2 = 12.345679 d3 = 123.45679 d4 = 1234.5679 d5 = 12345.679 default display d1 = 1.2345679 d2 = 12.345679 d3 = 123.45679 d4 = 1234.5679 d5 = 12345.679 setbase(16) l1 = 10 l2 = 100 l3 = 400 l4 = 1000 l5 = 10000 setbase(8) l1 = 20 l2 = 400 l3 = 2000 l4 = 10000 l5 = 200000 setbase(10) l1 = 16 l2 = 256 l3 = 1024 l4 = 4096 l5 = 65536
Использование манипуляторов
Система ввода/вывода С++ включает второй способ изменения параметров форматирования потока. Для этого используются специальные функции, называемые манипуляторами (manipulators), которые могут включаться в выражения ввода/вывода. Стандартные манипуляторы показаны в таблице.
| Манипулятор | Назначение | Ввод/вывод |
|---|---|---|
| dec | Ввод/вывод данных в десятичной форме | ввод и вывод |
| endl | Вывод символа новой строки с передачей в поток всех данных из буфера | вывод |
| ends | Вывод нулевого символа | вывод |
| flush | Передача в поток содержимого буфера | вывод |
| hex | Ввод/вывод данных в шестнадцатиричной системе | ввод и вывод |
| oct | Ввод/вывод данных в восьмеричной форме | ввод и вывод |
| resetiosflags(long f) | Сбрасывает флаги, указанные в f | ввод и вывод |
| setbase(int base) | Устанавливает базу счисления равной параметру base | вывод |
| setfill(int ch) | Устанавливает символ заполнения равным ch | вывод |
| setiosflags(long f) | Устанавливает флаги, указанные в f | ввод и вывод |
| setprecision(int p) | Устанавливает число цифр после запятой | вывод |
| setw(int w) | Устанавливает ширину поля равной w | вывод |
| ws | Пропускает начальный символ-разделитель | ввод |
Для использования манипуляторов с параметрами в программу необходимо включить заголовочный файл iomanip.h.
Манипуляторы могут использоваться в составе выражений ввода/вывода. Ниже представлен пример программы, использующей манипуляторы для изменения формата вывода:
Программа выводит следующие данные:
1000 .24
Hello there.
Обратим внимание, как манипуляторы появляются в последовательности операторов ввода/вывода. Когда манипуляторы не имеют аргументов, как манипулятор endl в этой программе, за ними не следуют скобки. Причина этого в том, что оператору
Следующая программа использует функции setiosflags() для установки флагов scientific и showpos потока cout:
Следующая программа использует манипулятор ws для пропуска идущих вначале символов- разделителей при вводе строки в переменную s: