Manipulação de Grandes Inteiros e Aritmética Básica em C++
Em competições de programação e no estudo de algoritmos, frequentemente nos deparamos com operações matemáticas que excedem os limites dos tipos de dados primitivos padrão. Para resolver esses problemas, é necessário implementar algoritmos que simulem as operações aritméticas manuais, manipulando os números dígito a dígito.
Multiplicação de Grandes Inteiros
A multiplicação de números com muitos dígitos requer a simulação do processo de multiplicação em coluna. Utilizamos um vetor para armazenar os resultados inetrmediários, acumulando os produtos e gerenciando os transportes (carries) para as posições mais significativas. O tamanho máximo do resultado será a soma dos tamanhos dos dois opperandos.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string executarMultiplicacao(const string& fator1, const string& fator2) {
if (fator1 == "0" || fator2 == "0") return "0";
vector<int> produto(fator1.length() + fator2.length(), 0);
for (int i = fator1.length() - 1; i >= 0; --i) {
for (int j = fator2.length() - 1; j >= 0; --j) {
int mul = (fator1[i] - '0') * (fator2[j] - '0');
int soma = mul + produto[i + j + 1];
produto[i + j + 1] = soma % 10;
produto[i + j] += soma / 10;
}
}
string resultado = "";
for (int digito : produto) {
if (!(resultado.empty() && digito == 0)) {
resultado += to_string(digito);
}
}
return resultado.empty() ? "0" : resultado;
}
int main() {
string a, b;
if (cin >> a >> b) {
cout << executarMultiplicacao(a, b) << "\n";
}
return 0;
}
Subtração de Grandes Inteiros
A subtração de grandes números introduz a complexidade do gerenciamento de empréstimos (borrows) entre as casas decimais. Além disso, o algoritmo deve ser capaz de comparar as magnitudes dos operadnos para determinar o sinal do resultado final, garantindo que a subtração seja sempre realizada do maior para o menor valor absoluto.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool ehMaiorOuIgual(const vector<int>& num1, const vector<int>& num2) {
if (num1.size() != num2.size()) {
return num1.size() > num2.size();
}
for (int i = num1.size() - 1; i >= 0; --i) {
if (num1[i] != num2[i]) {
return num1[i] > num2[i];
}
}
return true;
}
vector<int> calcularDiferenca(const vector<int>& minuendo, const vector<int>& subtraendo) {
vector<int> diferenca;
int emprestimo = 0;
for (size_t i = 0; i < minuendo.size(); ++i) {
int sub = minuendo[i] - emprestimo;
if (i < subtraendo.size()) {
sub -= subtraendo[i];
}
if (sub < 0) {
diferenca.push_back(sub + 10);
emprestimo = 1;
} else {
diferenca.push_back(sub);
emprestimo = 0;
}
}
while (diferenca.size() > 1 && diferenca.back() == 0) {
diferenca.pop_back();
}
return diferenca;
}
int main() {
string strA, strB;
if (cin >> strA >> strB) {
vector<int> A, B;
for (int i = strA.length() - 1; i >= 0; --i) A.push_back(strA[i] - '0');
for (int i = strB.length() - 1; i >= 0; --i) B.push_back(strB[i] - '0');
if (ehMaiorOuIgual(A, B)) {
vector<int> res = calcularDiferenca(A, B);
for (int i = res.size() - 1; i >= 0; --i) cout << res[i];
} else {
vector<int> res = calcularDiferenca(B, A);
cout << "-";
for (int i = res.size() - 1; i >= 0; --i) cout << res[i];
}
cout << "\n";
}
return 0;
}
Cálculo Aritmético Básico
Para expressões matemáticas simples que envolvem adição e divisão, como o cálculo de (a + b) / c, a atenção deve estar voltada para a precedência dos operadores e a prevenção de estouro de dados (overflow) durante a fase de soma, utilizando tipos de dados de maior capacidade quando necessário.
#include <iostream>
using namespace std;
int main() {
long long a, b, c;
if (cin >> a >> b >> c) {
if (c != 0) {
long long resultado = (a + b) / c;
cout << resultado << "\n";
}
}
return 0;
}