C++. Сборник рецептов.

10.2. Форматирование вывода чисел с плавающей точкой.

Проблема.

Требуется выдать числа с плавающей точкой в удобном формате либо ради обеспечения необходимой точности (применяя нотацию, которая используется в науке, а не в виде числа с фиксированной точкой), либо просто выравнивая значения по десятичной точке для лучшего восприятия.

Решение.

Используйте стандартные манипуляторы, определенные в <iomanip> и <ios>, для управления форматом значений чисел с плавающей точкой при их записи в поток. Это можно делать очень многими способами, и в примере 10.3 предлагается несколько способов отображения значения числа «пи».

Пример 10.3. Форматирование числа «пи».

#include <iostream>

#include <iomanip>

#include <string>

Using namespace std;

Int main() {

 ios_base::fmtflags flags = // Сохранить старые флаги.

 cout.flags();

 double pi = 3.14285714;

 cout << "pi = " << setprecision(5) // Обычный (стандартный) режим;

  << pi << '\n';                    // показать только 5 цифр в сумме.

                                    // по обе стороны от точки.

 cout << "pi = " << fixed // Режим чисел с фиксированной точкой;

  << showpos              // выдать "+" для положительных чисел.

  << setprecision(3)      // показать 3 цифры *справа* от.

  << pi << '\n';          // десятичной точки.

 cout << "pi = " << scientific // Режим научного представления;

  << noshowpos                 // знак плюс больше не выдается.

  << pi * 1000 << '\n';

 cout.flags(flags); // Восстановить значения флагов.

}

Это приведет к получению следующего результата.

Pi = 3.1429.

Pi = +3.143.

Pi = 3.143е+003.

Обсуждение.

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

Обычный (стандартный).

В этом формате фиксировано количество отображаемых цифр (по умолчанию это количество равно шести), а десятичная точка отображается в соответствующем месте. Поэтому число «пи» по умолчанию будет иметь вид 3.14286, а умноженное на 100 будет отображаться как 314.286.

Фиксированный.

В этом формате фиксировано количество цифр, отображаемое справа от десятичной точки, а количество цифр слева не фиксировано. В этом случае при стандартной точности, равной шести, число «пи» будет отображаться в виде 3.142857, а умноженное на 100 — 314.285714. В обоих случаях количество цифр, отображаемое справа от десятичной точки, равно шести, а общее количество цифр может быть любым.

Научный.

Значение начинается с цифры, затем идет десятичная точка и несколько цифр, количество которых определяется заданной точностью; затем идет буква «е» и степень 10, в которую надо возвести предыдущее значение. В этом случае число «пи», умноженное на 1000, будет отображаться как 3.142857е+003.

В табл. 10.2 приводятся все манипуляторы, которые воздействуют на вывод чисел с плавающей точкой (а иногда и на вывод любых чисел). См. табл. 10.1, где приводятся манипуляторы общего типа, которые можно использовать совместно с манипуляторами чисел с плавающей точкой.

Табл. 10.2. Манипуляторы, работающие с любыми числами и числами с плавающей точкой.

Манипулятор Описание Пример вывода
fixed Показать значение чисел с плавающей точкой с фиксированным количеством цифр справа от десятичной точки При стандартной точности, равной шести цифрам: pi = 3.142857
scientific Показать значение чисел с плавающей точкой, применяя научную нотацию, в которой используется значение с десятичной точкой и экспонентный множитель pi * 1000 при стандартной точности, равной шести цифрам: pi = 3.142857е+003
setprecision Установить количество цифр, отображаемых в выводе (см. последующие объяснения) Число «пи» в стандартном формате при точности, равной трем цифрам: pi = 3.14
В фиксированном формате: pi = 3.143
В научном формате: pi = 3.143е+000
showpos noshowpos Показать знак «плюс» перед положительными числами. Это действует для чисел любого типа, с десятичной точкой или целых +3.14
showpoint noshowpoint Показать десятичную точку, даже если после нее идут одни нули. Это действует только для чисел с плавающей точкой и не распространяется на целые числа Следующая строка при точности, равной двум цифрам: cout << showpoint << 2.0 выдаст такой результат: 2.00
showbase noshowbase Показать основание числа, представленного в десятичном виде (основание отсутствует), в восьмеричном виде (ведущий нуль) или в шестнадцатеричном виде (префикс 0x). См. следующую строку таблицы Десятичное представление:  32 Восьмеричное:  040 Шестнадцатеричное:  0x20
dec oct hex Установить основание для отображения числа в десятичном, восьмеричном или шестнадцатеричном виде. Само основание по умолчанию не отображается; для его отображения используйте showbase См предыдущую строку таблицы
uppercase nouppercase Отображать значения, используя верхний регистр Устанавливает регистр вывода чисел, например для префикса 0X шестнадцатеричных чисел или буквы E для чисел, представленных в научной нотации

Все манипуляторы, кроме setprecision, одинаково воздействуют на все три формата. В стандартном режиме «точность» определяет суммарное количество цифр по обе стороны от десятичной точки. Например, для отображения числа «пи» в стандартном формате с точностью, равной 2, выполните следующие действия.

Cout << "pi = " << setprecision(2) << pi << '\n';

В результате вы получите.

Pi = 3.1.

Для сравнения представим, что вам требуется отобразить число «пи» в формате чисел с плавающей точкой.

Cout << "pi = " << fixed << setprecision(2) << pi << '\n';

Теперь результат будет таким.

Pi = 3.14.

Отличие объясняется тем, что здесь точность определяет количество цифр, расположенных справа от десятичной точки. Если мы умножим число «пи» на 1000 и отобразим в том же формате, количество цифр справа от десятичной точки не изменится.

Cout << "pi = " << fixed << setprecision(2) << pi * 1000 << '\n';

Выдает в результате:

Pi = 3142.86.

Это хорошо, потому что вы можете задать точность, установить ширину своего поля при помощи setw, выровнять вправо отображаемое значение при помощи right (см. рецепт 10.1), и ваши числа будут выровнены вертикально по десятичной точке.

Поскольку манипуляторы — это просто удобный способ установки флагов формата для потока, следует помнить, что заданные установки работают до тех пор, пока вы их не уберете или пока поток не будет уничтожен. Сохраните флаги формата (см. пример 10.3) до того, как вы начнете его изменять, и восстановите их в конце.

Смотри также.

Рецепт 10.3.