HOWTO · C++

Como usar o setprecision em C++

Este artigo explica como usar o manipulador de fluxo setprecision() em C++.

Nesta página

Em C++, std::setprecision(n) define a precisão dos valores de ponto flutuante subsequentes gravados em um fluxo. Com o formato padrão de ponto flutuante, n representa o número de dígitos significativos, e não o número de dígitos após o separador decimal. Use std::fixed quando precisar de um número fixo de dígitos após o separador decimal.

setprecision é um manipulador de fluxo declarado em <iomanip>. Os exemplos abaixo usam std::cout; as mesmas regras de estado de formatação se aplicam a outros fluxos de saída.

Como setprecision controla a precisão

Sem std::fixed nem std::scientific, a saída de ponto flutuante usa o formato padrão. Nesse formato, a precisão corresponde ao número de dígitos significativos. O fluxo arredonda o valor exibido para essa quantidade de dígitos; por isso, zeros à esquerda após o separador decimal não contam como dígitos significativos. O formato padrão pode escolher a notação comum ou científica de acordo com o valor e a precisão; definir uma precisão não significa que a notação científica comece sempre a partir de uma quantidade fixa de dígitos.

Execute este exemplo:

O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.

#include <iomanip>
#include <iostream>

int main() {
    std::cout << std::setprecision(5);
    std::cout << 123.456 << '\n';
    std::cout << 0.0123456 << '\n';
    std::cout << 1234567.0 << '\n';
}
123.46
0.012346
1.2346e+06

O primeiro valor é arredondado para cinco dígitos significativos. No segundo valor, os zeros à esquerda não consomem a precisão disponível. O formato padrão pode exibir o terceiro valor, que é grande, em notação científica. Para solicitar explicitamente essa notação, use std::scientific; nesse caso, a precisão indica o número de dígitos após o separador decimal. std::defaultfloat restaura o formato padrão.

Esses manipuladores alteram o estado de formatação do fluxo. A precisão definida com std::setprecision continua valendo para as inserções posteriores de valores de ponto flutuante nesse fluxo, até que outra precisão seja definida. Inclua <iomanip> em um programa que use std::setprecision.

Defina um número fixo de casas decimais com std::fixed

Combine std::fixed com std::setprecision(n) para imprimir exatamente n dígitos após o separador decimal. Isso é útil para valores como preços ou medidas que devem ter sempre o mesmo número de casas decimais. O fluxo arredonda o valor exibido quando necessário e acrescenta zeros à direita quando o valor tem menos dígitos fracionários.

O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.

#include <iomanip>
#include <iostream>

int main() {
    const double price = 12.5;
    const double measurement = 3.14159;

    std::cout << std::fixed << std::setprecision(2);
    std::cout << price << '\n';
    std::cout << measurement << '\n';
}
12.50
3.14

std::fixed afeta as saídas subsequentes de ponto flutuante nesse fluxo, e std::setprecision(2) continua ativa até ser alterada. Para voltar ao formato padrão de ponto flutuante, insira std::defaultfloat; se necessário, defina novamente a precisão desejada para as saídas seguintes.

Alinhe valores formatados em colunas

Para montar uma tabela simples, combine std::setw, std::right, std::setfill, std::fixed e std::setprecision. A largura definida por std::setw(n) vale apenas para o próximo valor inserido; por isso, chame-o para cada entrada da coluna. std::right coloca o preenchimento antes do valor, enquanto std::setfill escolhe o caractere de preenchimento. Com um número fixo de casas decimais, valores de magnitudes diferentes têm a mesma quantidade de dígitos fracionários, o que alinha os separadores decimais quando os valores são alinhados à direita em campos de mesma largura.

O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.

#include <iomanip>
#include <iostream>

int main() {
    const double values[] = {123.45, 2.5, 89.0};

    std::cout << std::fixed << std::setprecision(2)
              << std::right << std::setfill(' ');
    for (double value : values) {
        std::cout << std::setw(10) << value << '\n';
    }
}
    123.45
      2.50
     89.00

std::right, o caractere de preenchimento, o formato fixo e a precisão continuam fazendo parte do estado do fluxo nas inserções seguintes. A largura é a exceção: ela é consumida pela próxima inserção formatada, então aplique std::setw novamente para cada valor. Escolha uma largura de campo que comporte o maior valor; um campo não trunca um valor que exceda essa largura.