C++ Matemática (cmath)

Os operadores + - * / % fazem as contas básicas. Mas e a raiz quadrada? E "2 elevado a 10"? E arredondar a média da Ana? Para isso, o C++ traz uma caixa de ferramentas de matemática pronta, a biblioteca <cmath>. Nesta aula você vai usar as funções mais comuns dela, uma de cada vez, e ver o que acontece quando a conta não tem resposta, como a raiz de um número negativo.

Você vai aprender
  • O que é <cmath> e como chamar uma função de matemática.
  • Raiz e potência: std::sqrt, std::pow (e std::cbrt, a raiz cúbica).
  • Valor absoluto com std::abs, e a armadilha do abs sem std::, que corta o 2.75 para 2.
  • As quatro formas de arredondar: round, floor, ceil e trunc.
  • Maior e menor com std::max e std::min (de <algorithm>).
  • O número π pronto: std::numbers::pi C++20.
  • A distância entre dois pontos com std::hypot.
  • O que são nan e inf, e por que sqrt(-1) não trava o programa.

Todos os programas desta aula foram compilados com o g++ 15.2 na máquina fictícia da Ana (usuária ana, computador notebook), com o comando padrão do guia, g++ -std=c++23 -Wall -Wextra arquivo.cpp -o programa (explicado em Compilar com g++). Você pode repetir cada um no editor do guia, que compila C++ de verdade no navegador.


A ideia: a calculadora científica

Lembra da calculadora da escola? A simples tem só + − × ÷. A científica tem botões a mais: √, x², |x|, π. Os operadores do C++ (aula Operadores Aritméticos) são a calculadora simples. A <cmath> é a fileira de botões científicos.

Cada "botão" é uma função: um pedaço de código pronto, com um nome, que recebe valores entre parênteses e devolve um resultado. Você vai aprender a criar as suas em Funções; por enquanto, basta saber chamar as que já existem:

Na calculadoraEm C++Resultado
√25std::sqrt(25)5
2¹⁰std::pow(2, 10)1024
|−7|std::abs(-7)7
πstd::numbers::pi3.14159…

O nome cmath quer dizer "C math", a matemática que veio da linguagem C. O c no começo marca as bibliotecas herdadas do C (como <cstdlib> e <cstdio>).


1. Raiz e potência: sqrt e pow

Para usar as funções, inclua <cmath> no topo do arquivo, ao lado do <iostream>:

#include <iostream>
#include <cmath>

int main() {
    std::cout << std::sqrt(25) << "\n";
    std::cout << std::sqrt(2) << "\n";
    std::cout << std::pow(2, 10) << "\n";
    std::cout << std::pow(1.5, 2) << "\n";
    std::cout << std::pow(27, 1.0 / 3) << "\n";
    std::cout << std::cbrt(27) << "\n";
}
#include <cmath>
Traz as funções de matemática para o seu programa. Sem essa linha, o compilador não conhece std::sqrt (o erro está em "Quando dá errado").
std::
O "sobrenome" das coisas da biblioteca padrão (standard). std::sqrt = "o sqrt da biblioteca padrão". A aula Namespaces explica o porquê.
sqrt(25)
square root, raiz quadrada. O valor entre parênteses é o argumento: o número de que você quer a raiz.
pow(2, 10)
power, potência: a base (2) elevada ao expoente (10). Dois argumentos, separados por vírgula. Em C++ não existe operador ^ de potência: 2 ^ 10 compila, mas é outra coisa (uma operação de bits) e dá 8. O g++ 15 desconfia e avisa: warning: result of ‘2^10’ is 8; did you mean ‘1 << 10’ (1024)? [-Wxor-used-as-pow].
pow(27, 1.0 / 3)
Elevar a 1/3 é tirar a raiz cúbica. Repare no 1.0: com 1 / 3, a divisão de inteiros daria 0 (aula Operadores Aritméticos).
cbrt(27)
cube root, raiz cúbica, direto.
$ g++ -std=c++23 -Wall -Wextra raiz.cpp -o raiz
$ ./raiz
5
1.41421                  « √2 tem infinitas casas; o cout mostra 6 algarismos
1024
2.25
3
3

Duas coisas para reparar:

  • O resultado é double (número com vírgula, aula float e double), mesmo quando a conta dá "redondo". std::sqrt(25) devolve 5.0; o cout só esconde o .0.
  • O cout mostra no máximo 6 algarismos. Por isso √2 virou 1.41421. Números grandes viram notação científica: std::pow(2, 30) aparece como 1.07374e+09 (1,07374 × 10⁹). Para escolher quantas casas mostrar, veja Formatar com iomanip e std::format e std::print.
E o -lm?

Em tutoriais da linguagem C, você vai ver gcc programa.c -lm: o -lm manda "ligar" a biblioteca de matemática (libm). Em C++ ele não é necessário: o g++ sempre liga a biblioteca do C++ (libstdc++), que já depende da libm. O ldd (que lista as bibliotecas de um programa) mostra que ela entrou sozinha:

$ ldd ./raiz
	linux-vdso.so.1 (0x00007ae3a075e000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ae3a0400000)
	libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007ae3a02da000)     « aqui
	libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007ae3a0000000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ae3a0760000)
	libgcc_s.so.1 => /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ae3a0708000)

Os números entre parênteses são endereços de memória e mudam a cada execução.

Missão: complete as duas linhas para mostrar a raiz quadrada de 144 e 3 elevado a 4. A saída deve ser 12 e 81.

#include <iostream>
#include <cmath>

int main() {
    std::cout << "Raiz de 144: " << 0 << "\n";
    std::cout << "3 elevado a 4: " << 0 << "\n";
}
#include <iostream>
#include <cmath>

int main() {
    std::cout << "Raiz de 144: " << std::sqrt(144) << "\n";
    std::cout << "3 elevado a 4: " << std::pow(3, 4) << "\n";
}

2. Valor absoluto: std::abs

O valor absoluto é o número "sem o sinal": a distância até o zero. |−7| = 7 e |7| = 7. Serve, por exemplo, para saber de quanto é uma dívida sem se preocupar se o saldo está negativo.

#include <iostream>
#include <cmath>

int main() {
    std::cout << std::abs(-7) << "\n";
    std::cout << std::abs(-2.5) << "\n";
    std::cout << abs(-2.5) << "\n";
}
$ g++ -std=c++23 -Wall -Wextra abs.cpp -o abs
$ ./abs
7
2.5
2                        « abs sem std:: cortou o .5, e o g++ não avisou nada!

As duas primeiras linhas estão certas. A terceira mostrou 2 em vez de 2.5, e o compilador ficou calado mesmo com -Wall -Wextra. O que aconteceu?

  • O std::abs do C++ tem uma versão para cada tipo de número: uma para int, uma para double, uma para long… O compilador escolhe a certa olhando o argumento. Isso se chama sobrecarga (aula Sobrecarga de Funções).
  • O abs sem std:: é o antigo da linguagem C, que só conhece int. O -2.5 foi convertido para int (virou -2, perdendo o .5) antes do cálculo.

Só a opção -Wconversion (que não faz parte de -Wall -Wextra, aula Avisos) denuncia a perda:

$ g++ -std=c++23 -Wall -Wextra -Wconversion abs.cpp -o abs
abs.cpp: In function ‘int main()’:
abs.cpp:7:22: warning: conversion from ‘double’ to ‘int’ changes value from ‘-2.5e+0’ to ‘-2’ [-Wfloat-conversion]
    7 |     std::cout << abs(-2.5) << "\n";
      |                      ^~~~

Tradução: "conversão de double para int muda o valor de −2,5 para −2". O outro compilador do laboratório, o Clang (o mesmo do editor do guia), avisa mesmo sem -Wconversion, e ainda sugere a correção:

$ clang++ -std=c++23 -Wall -Wextra abs.cpp -o abs
abs.cpp:7:18: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value]
    7 |     std::cout << abs(-2.5) << "\n";
      |                  ^
abs.cpp:7:18: note: use function 'std::abs' instead
    7 |     std::cout << abs(-2.5) << "\n";
      |                  ^~~
      |                  std::abs
abs.cpp:7:22: warning: implicit conversion from 'double' to 'int' changes value from -2.5 to -2 [-Wliteral-conversion]
    7 |     std::cout << abs(-2.5) << "\n";
      |                  ~~~ ^~~~
2 warnings generated.
Regra prática: sempre std::abs

Com std::, o resultado é certo para qualquer tipo. Sem ele, o resultado depende de qual cabeçalho você incluiu: no laboratório, com <cmath> ou <cstdlib>, abs(-2.75) deu 2; com o antigo <stdlib.h>, deu 2.75. No editor do guia, que usa outra biblioteca padrão (a libc++, do projeto LLVM), o resultado também pode ser outro. Programa que muda de resposta conforme o #include ou a biblioteca é armadilha. Você também vai ver fabs (o "abs para double" do C) em código antigo; em C++, std::abs já resolve.


3. Arredondar: round, floor, ceil e trunc

Existem quatro jeitos de transformar 2.7 num número inteiro, e cada um serve para uma situação:

FunçãoNome em inglêsO que faz
std::roundround, arredondarVai para o inteiro mais perto. No meio exato (.5), vai para longe do zero.
std::floorfloor, chãoDesce para o inteiro de baixo.
std::ceilceiling, tetoSobe para o inteiro de cima.
std::trunctruncate, cortarJoga fora as casas decimais, sem arredondar.
#include <iostream>
#include <cmath>

int main() {
    double v[] = {2.4, 2.5, 2.7, -2.5, -2.7};
    for (double x : v) {
        std::cout << x << ": round=" << std::round(x) << " floor=" << std::floor(x)
                  << " ceil=" << std::ceil(x) << " trunc=" << std::trunc(x) << "\n";
    }
}

Este programa usa duas coisas de aulas futuras só para não repetir a mesma linha cinco vezes: uma lista de números (double v[], aula Arrays) e um for que passa por cada um deles, chamando-o de x (aula for de Intervalo). Foque nas funções:

$ ./arred
2.4: round=2 floor=2 ceil=3 trunc=2
2.5: round=3 floor=2 ceil=3 trunc=2
2.7: round=3 floor=2 ceil=3 trunc=2
-2.5: round=-3 floor=-3 ceil=-2 trunc=-2    « nos negativos, "baixo" é -3
-2.7: round=-3 floor=-3 ceil=-2 trunc=-2

Nos positivos, floor e trunc dão o mesmo resultado. A diferença aparece nos negativos: o floor desce (−2,5 → −3), o trunc só corta (−2,5 → −2). Pense num termômetro: abaixo de zero, "descer" é ficar mais frio.

Quando usar cada um

SituaçãoFunçãoExemplo
Mostrar uma média "redonda"std::roundmédia 6,75 → 7
Quantas caixas, ônibus, viagens são necessáriasstd::ceil23 ovos em caixas de 6 → 4 caixas (sobra uma meio vazia, mas precisa dela)
Quantos itens cabem inteirosstd::floorcom R$ 20, a R$ 3 cada → 6 cadernos
Só a parte inteira, ignorando o restostd::truncidade a partir de 29,9 anos → 29

Arredondar com uma casa decimal

As quatro funções sempre arredondam para um inteiro. Para ficar com uma casa, o truque é multiplicar por 10, arredondar e dividir por 10:

#include <iostream>
#include <cmath>

int main() {
    double media = 6.75;
    std::cout << "Média: " << media << "\n";
    std::cout << "Arredondada: " << std::round(media) << "\n";
    std::cout << "Com 1 casa: " << std::round(media * 10) / 10 << "\n";
}
$ ./nota
Média: 6.75
Arredondada: 7
Com 1 casa: 6.8          « 67.5 → round → 68 → ÷10 → 6.8

Se a ideia é só mostrar o número com uma casa (e não mudar o valor guardado), é mais simples pedir isso na hora de imprimir, com iomanip ou std::format.

Quero um int, não um double

std::round(2.5) devolve 3.0, um double. Se você precisa de um inteiro de verdade (para contar, ou usar como posição numa lista), use std::lround(2.5), que devolve um long com o valor 3. A conversão entre tipos é assunto de Conversão de Tipos.

Missão: a Ana tem 23 ovos e cada caixa leva 6. O programa diz que ela precisa de 3 caixas, mas aí sobram ovos de fora! Use std::ceil para mostrar Caixas: 4. Cuidado: 23 / 6 com dois inteiros já dá 3 antes de o ceil entrar em ação.

#include <iostream>
#include <cmath>

int main() {
    int ovos = 23;
    int caixas = ovos / 6;
    std::cout << "Caixas: " << caixas << "\n";
}
#include <iostream>
#include <cmath>

int main() {
    int ovos = 23;
    double caixas = std::ceil(ovos / 6.0);
    std::cout << "Caixas: " << caixas << "\n";
}

4. Maior e menor: std::max e std::min

Para escolher o maior ou o menor de dois valores, use std::max e std::min. Eles não moram na <cmath>, e sim na <algorithm> (algoritmos), outra biblioteca padrão:

#include <iostream>
#include <algorithm>

int main() {
    std::cout << std::max(3, 7) << "\n";
    std::cout << std::min(3, 7) << "\n";
    std::cout << std::max({8, 3, 9, 5}) << "\n";
}
$ ./maxmin
7
3
9                        « com chaves { }, aceita quantos valores você quiser
std::max(3, 7)
Devolve o maior dos dois: 7.
std::min(3, 7)
Devolve o menor: 3.
std::max({8, 3, 9, 5})
Com uma lista entre chaves, compara todos de uma vez. Repare: parênteses e chaves.

Os dois valores precisam ser do mesmo tipo. std::max(3, 7.5) (um int e um double) não compila; veja o erro em "Quando dá errado". Um uso comum é "não deixar passar do limite": std::min(nota, 10.0) garante que a nota nunca passe de 10, mesmo com bônus.


5. O número π: std::numbers::pi C++20

Desde o C++20, o π vem pronto, com todas as casas que um double consegue guardar, na biblioteca <numbers>:

#include <iostream>
#include <numbers>

int main() {
    double raio = 2.0;
    double area = std::numbers::pi * raio * raio;
    std::cout << "Área: " << area << "\n";
}
$ g++ -std=c++23 -Wall -Wextra pi.cpp -o pi
$ ./pi
Área: 12.5664
#include <numbers>
A biblioteca das constantes matemáticas (C++20).
std::numbers::pi
Leia de trás para frente: "o pi, que está em numbers, que está em std". Não tem parênteses: é um valor, não uma função.
raio * raio
O raio ao quadrado. Também daria std::pow(raio, 2) (com <cmath>).

Na mesma biblioteca estão std::numbers::e (2.71828…, o número de Euler) e std::numbers::sqrt2 (√2 = 1.41421…).

Por que o -std=c++23 é obrigatório aqui

O g++ 15, se você não disser nada, compila como C++17, que ainda não tinha <numbers>. Sem o -std=:

$ g++ -Wall -Wextra pi.cpp -o pi
pi.cpp: In function ‘int main()’:
pi.cpp:6:24: error: ‘std::numbers’ has not been declared
    6 |     double area = std::numbers::pi * raio * raio;
      |                        ^~~~~~~

"std::numbers não foi declarado". Em código antigo, você vai ver duas alternativas: M_PI (uma constante do sistema, que não faz parte do padrão C++) ou o π digitado à mão, const double PI = 3.14159265358979; (veja Constantes). Com C++20 ou mais novo, prefira std::numbers::pi.


6. Distância entre dois pontos: std::hypot

A casa da Ana fica 3 quarteirões a leste e 4 ao norte da padaria. Em linha reta, qual a distância? É o teorema de Pitágoras: √(3² + 4²) = 5. A função std::hypot (de hypotenuse, hipotenusa) faz essa conta de uma vez:

#include <iostream>
#include <cmath>

int main() {
    std::cout << std::hypot(3, 4) << "\n";
    std::cout << std::sqrt(3 * 3 + 4 * 4) << "\n";
}
$ ./hypot
5
5

As duas linhas dão o mesmo resultado. O hypot é mais curto de ler e, com números muito grandes ou muito pequenos, mais preciso (ele evita que o quadrado "estoure" no meio da conta).


7. Conta sem resposta: nan e inf

Não existe raiz quadrada de número negativo nos números reais. O que o C++ faz com std::sqrt(-1)? Ele não trava o programa: devolve um valor especial chamado NaN (Not a Number, "não é um número").

#include <iostream>
#include <cmath>

int main() {
    double r = std::sqrt(-1);
    std::cout << r << "\n";
    std::cout << std::log(0) << "\n";
    std::cout << 1.0 / 0 << "\n";
    std::cout << std::isnan(r) << "\n";
    std::cout << (r == r) << "\n";
}
$ g++ -std=c++23 -Wall -Wextra nan.cpp -o nan
nan.cpp: In function ‘int main()’:
nan.cpp:8:22: warning: division by zero [-Wdiv-by-zero]
    8 |     std::cout << 1.0 / 0 << "\n";
      |                  ~~~~^~~
$ ./nan
-nan                     « sqrt(-1): "não é um número" (o sinal de menos não significa nada útil)
-inf                     « log(0): menos infinito
inf                      « 1.0 / 0: infinito
1                        « isnan(r) é verdadeiro (1 = true)
0                        « um NaN não é igual nem a ele mesmo!
ValorQuer dizerDe onde vem
nan / -nan"Não é um número": a conta não tem respostastd::sqrt(-1), 0.0 / 0, conta com outro nan
inf / -infInfinito (positivo ou negativo)1.0 / 0, std::log(0), número grande demais

O perigo é que o nan contamina tudo: qualquer conta com ele dá nan, e o programa segue em frente mostrando lixo. Para descobrir se um resultado é nan, use std::isnan(x) (não x == x, que é um truque confuso). Na aula if e else você vai aprender a conferir antes: "se o número for negativo, avise o usuário em vez de calcular a raiz".

1.0 / 0 dá inf, mas 1 / 0 não

A divisão por zero só dá inf com números com vírgula (double). Com dois inteiros, 1 / 0 é comportamento indefinido: no laboratório, o programa morreu sem mostrar nada, com código de saída 136 (aula Comportamento Indefinido). Nos dois casos, o g++ avisa com -Wdiv-by-zero quando o zero está escrito no código.


Formas diferentes de fazer a mesma conta

ContaFormasQual usar
x²x * x · std::pow(x, 2)x * x é simples e exato com inteiros; pow sempre devolve double. Para expoentes maiores ou com vírgula, pow.
Raiz cúbicastd::cbrt(x) · std::pow(x, 1.0 / 3)cbrt: mais claro, e funciona com negativos (pow(-8, 1.0/3) dá nan).
πstd::numbers::pi · M_PI · 3.14159… à mãostd::numbers::pi (C++20). Os outros só em código antigo.
Hipotenusastd::hypot(a, b) · std::sqrt(a*a + b*b)hypot: mais curto e mais preciso.
Valor absolutostd::abs(x) · abs(x) · fabs(x)Sempre std::abs.

Quando dá errado

error: ‘sqrt’ is not a member of ‘std’; did you mean ‘sort’?
#include <iostream>

int main() {
    std::cout << std::sqrt(16) << "\n";
}
$ g++ -std=c++23 -Wall -Wextra semcmath.cpp -o semcmath
semcmath.cpp: In function ‘int main()’:
semcmath.cpp:4:23: error: ‘sqrt’ is not a member of ‘std’; did you mean ‘sort’?
    4 |     std::cout << std::sqrt(16) << "\n";
      |                       ^~~~
      |                       sort

O que significa: "sqrt não é um membro de std". O compilador não conhece a função porque faltou o #include <cmath>. A sugestão "você quis dizer sort?" é só um palpite por nomes parecidos: ignore.

Como consertar: acrescente #include <cmath> no topo. Regra geral: para cada coisa que você usa da biblioteca, inclua o cabeçalho dela, mesmo que às vezes funcione sem (outro cabeçalho pode trazê-la "de carona", mas isso muda de compilador para compilador).

error: no matching function for call to ‘max(int, double)’
    std::cout << std::max(3, 7.5) << "\n";

A mensagem completa tem mais de 30 linhas. As que importam são a primeira e esta:

$ g++ -std=c++23 -Wall -Wextra maxmin.cpp -o maxmin
maxmin.cpp: In function ‘int main()’:
maxmin.cpp:8:26: error: no matching function for call to ‘max(int, double)’
    8 |     std::cout << std::max(3, 7.5) << "\n";
      |                  ~~~~~~~~^~~~~~~~
maxmin.cpp:8:26: note: there are 4 candidates
…
maxmin.cpp:8:26: note:   deduced conflicting types for parameter ‘const _Tp’ (‘int’ and ‘double’)

O que significa: "nenhuma função combina com a chamada max(int, double)". O std::max exige que os dois valores tenham o mesmo tipo, e recebeu um int (3) e um double (7.5): "tipos conflitantes (int e double)". As notas candidate 1, candidate 2… listam as versões de max que existem e por que nenhuma serviu.

Como consertar: deixe os dois do mesmo tipo: std::max(3.0, 7.5). Ou diga o tipo explicitamente: std::max<double>(3, 7.5). A aula Lendo Erros do Compilador ensina a achar a linha importante nesses erros longos.

O programa mostra nan ou -nan

O que significa: alguma conta não tinha resposta: raiz de negativo, 0.0 / 0, logaritmo de negativo. Dali em diante, tudo que usou esse valor também virou nan.

Como consertar: procure a primeira conta que gerou o nan (mostre os valores intermediários com cout) e confira os dados antes de calcular, com um if.

abs devolve um número sem as casas decimais

O que significa: você usou abs sem std::, que é a versão do C só para inteiros.

Como consertar: escreva std::abs.

std::ceil(23 / 6) dá 3, não 4

O que significa: a divisão 23 / 6 é feita antes, entre dois inteiros, e já dá 3. O ceil recebe 3 e não tem o que arredondar.

Como consertar: faça a divisão com double: std::ceil(23 / 6.0) ou std::ceil(static_cast<double>(ovos) / 6) (veja Conversão de Tipos).


Referência rápida

FunçãoCabeçalhoO que fazExemplo → resultado
std::sqrt(x)<cmath>Raiz quadradasqrt(25) → 5
std::cbrt(x)<cmath>Raiz cúbicacbrt(27) → 3
std::pow(b, e)<cmath>b elevado a epow(2, 10) → 1024
std::abs(x)<cmath>Valor absoluto (qualquer tipo)abs(-2.5) → 2.5
std::round(x)<cmath>Inteiro mais pertoround(2.5) → 3
std::floor(x)<cmath>Arredonda para baixofloor(-2.5) → -3
std::ceil(x)<cmath>Arredonda para cimaceil(2.1) → 3
std::trunc(x)<cmath>Corta as casas decimaistrunc(-2.7) → -2
std::lround(x)<cmath>Como round, mas devolve longlround(2.5) → 3
std::hypot(a, b)<cmath>√(a² + b²)hypot(3, 4) → 5
std::isnan(x)<cmath>true se x é NaNisnan(sqrt(-1)) → 1
std::max(a, b), std::min(a, b)<algorithm>Maior / menor (mesmo tipo)max(3, 7) → 7
std::max({a, b, c})<algorithm>Maior de uma listamax({8, 3, 9}) → 9
std::numbers::pi<numbers> (C++20)π3.14159…

A <cmath> tem muito mais: std::sin, std::cos, std::tan (trigonometria, com ângulos em radianos), std::log (logaritmo natural), std::log10, std::exp. Elas funcionam do mesmo jeito: inclua <cmath> e chame com std::.


Exercícios

1. A raiz

Complete para mostrar a raiz quadrada de 81:

std::cout << std::(81);

2. O cabeçalho

Qual cabeçalho você precisa incluir para usar std::max?

#include <>

3. Quanto vale std::floor(-3.2)?

4. Um ônibus leva 40 pessoas. Para levar 130 alunos, qual função calcula quantos ônibus são necessários?

5. O que std::cout << std::sqrt(-4); mostra?

6. Por que preferir std::abs(x) a abs(x)?

Missão final: o canteiro redondo

Missão: a Ana vai adubar um canteiro redondo de raio 5 metros. Calcule a área (π × raio²) usando std::numbers::pi e mostre Área: 78.5398. Cada saco de adubo cobre 10 m²: mostre quantos sacos ela precisa comprar (Sacos: 8), arredondando para cima.

#include <iostream>
#include <cmath>
#include <numbers>

int main() {
    double raio = 5.0;
    // calcule a área aqui

    // e quantos sacos de 10 m² ela precisa
}
#include <iostream>
#include <cmath>
#include <numbers>

int main() {
    double raio = 5.0;
    double area = std::numbers::pi * std::pow(raio, 2);
    double sacos = std::ceil(area / 10);
    std::cout << "Área: " << area << "\n";
    std::cout << "Sacos: " << sacos << "\n";
}

Resumo

  • #include <cmath> traz as funções de matemática. Chame-as com std::: std::sqrt(25).
  • std::sqrt (raiz), std::pow(b, e) (potência; C++ não tem ^ de potência), std::cbrt (raiz cúbica). O resultado é double.
  • Use sempre std::abs: o abs sem std:: pode ser a versão do C, só para int, e transformar 2.5 em 2 sem aviso do g++.
  • round (mais perto), floor (para baixo), ceil (para cima), trunc (corta). Cuidado com a divisão de inteiros antes do arredondamento.
  • std::max e std::min vêm de <algorithm> e exigem dois valores do mesmo tipo.
  • std::numbers::pi (<numbers>, C++20) precisa de -std=c++20 ou mais novo.
  • std::sqrt(-1) não trava: devolve nan. Divisão de double por zero dá inf. Teste com std::isnan.
  • Em C++, não precisa de -lm: o g++ já liga a biblioteca de matemática.