Возведение чисел в квадрат на C++

Возведение числа в квадрат  —  фундаментальная операция в математике и программировании. На C++ она осуществляется несколькими способами, у каждого из которых имеются преимущества и варианты использования. Изучим эти методы и посмотрим, как они применяются в реальных сценариях.

Базовый метод: умножение

Простейший способ возведения числа в квадрат на C++  —  умножить его само на себя. Вот простой пример:

#include <iostream>

int main() {
int number = 5;
int squared = number * number;
std::cout << number << " squared is " << squared << std::endl;
return 0;
}

Вывод:

5 squared is 25

Этот метод прост и хорош для работы с целочисленными типами. Но имеется риск целочисленного переполнения, поэтому будьте осторожны с большими числами.

Применение функции pow()

Для большей гибкости, особенно при работе с числами с плавающей точкой, воспользуйтесь функцией pow() из библиотеки <cmath>:

#include <iostream>
#include <cmath>

int main() {
double number = 5.5;
double squared = std::pow(number, 2);
std::cout << number << " squared is " << squared << std::endl;
return 0;
}

Вывод:

5.5 squared is 30.25

Функцией pow() вычисляется любая степень, не только квадраты. Но на простых операциях возведения в квадрат она чуть медленнее, чем непосредственное умножение.

Создание функции возведения в квадрат

Чтобы усовершенствовать организацию и переиспользуемость кода, создается специальная функция для возведения чисел в квадрат:

#include <iostream>

template <typename T>
T square(T number) {
return number * number;
}

int main() {
std::cout << "Square of 5: " << square(5) << std::endl;
std::cout << "Square of 3.14: " << square(3.14) << std::endl;
return 0;
}

Вывод:

Square of 5: 25
Square of 3.14: 9.8596

Этой шаблонной функцией обеспечиваются гибкость и простота при работе с любым числовым типом.

Работа с большими числами

Имея дело с большими числами, остерегайтесь возможного переполнения. Вот пример использования целых чисел long long:

#include <iostream>
#include <limits>

long long safe_square(long long number) {
if (number > std::sqrt(std::numeric_limits<long long>::max()) ||
number < -std::sqrt(std::numeric_limits<long long>::max())) {
throw std::overflow_error("Squaring this number would cause an overflow");
}
return number * number;
}

int main() {
try {
std::cout << "Square of 1000000: " << safe_square(1000000) << std::endl;
std::cout << "Square of 3037000500: " << safe_square(3037000500LL) << std::endl;
} catch (const std::overflow_error& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}

Вывод:

Square of 1000000: 1000000000000
Error: Squaring this number would cause an overflow

Этой функцией проверяется, нет ли при возведении числа в квадрат превышения максимального значения для long long. Если оно превышено, выбрасывается исключение.

Возведение комплексных чисел в квадрат

А вот как на C++ возводятся в квадрат комплексные числа:

#include <iostream>
#include <complex>

int main() {
std::complex<double> c(3, 4); // 3 + 4i
std::complex<double> squared = c * c;
std::cout << "(" << c.real() << " + " << c.imag() << "i) squared is "
<< squared.real() << " + " << squared.imag() << "i" << std::endl;
return 0;
}

Вывод:

(3 + 4i) squared is -7 + 24i

В этом примере показывается, как комплексное число возводится в квадрат по формуле (a + bi)² = (a² — b²) + 2abi.

Реальное применение: вычисление расстояния

Рассмотрим практический сценарий с вычислением евклидова расстояния между двумя точками на двумерной плоскости:

#include <iostream>
#include <cmath>

struct Point {
double x, y;
};

double distance(const Point& p1, const Point& p2) {
double dx = p2.x - p1.x;
double dy = p2.y - p1.y;
return std::sqrt(dx*dx + dy*dy);
}

int main() {
Point p1 = {0, 0};
Point p2 = {3, 4};
std::cout << "Distance between points: " << distance(p1, p2) << std::endl;
return 0;
}

Вывод:

Distance between points: 5

В этом примере возведение в квадрат используется как часть формулы расчета расстояния: √((x₂-x₁)² + (y₂-y₁)²).

Оптимизация вычислений квадратов чисел

Там, где важна производительность, операции возведения в квадрат оптимизируются. Вот сравнение различных методов:

#include <iostream>
#include <chrono>
#include <cmath>
#include <functional>

template <typename Func>
double benchmark(Func f, int iterations) {
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
volatile double result = f(i % 100); // Оптимизация предотвращается
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
return diff.count();
}

double multiply_square(double x) { return x * x; }
double pow_square(double x) { return std::pow(x, 2); }

int main() {
const int ITERATIONS = 10000000;

double multiply_time = benchmark(multiply_square, ITERATIONS);
double pow_time = benchmark(pow_square, ITERATIONS);

std::cout << "Time taken for " << ITERATIONS << " iterations:" << std::endl;
std::cout << "Multiplication: " << multiply_time << " seconds" << std::endl;
std::cout << "std::pow: " << pow_time << " seconds" << std::endl;

return 0;
}

В этом тесте производительности непосредственное умножение сравнивается со std::pow(). Результаты варьируются в зависимости от вашей системы и оптимизаций компилятора, но на простых операциях возведения в квадрат непосредственное умножение в целом быстрее.

Возведение в квадрат в побитовых операциях

При программировании низкоуровневых или встраиваемых систем может потребоваться возводить числа в квадрат побитовыми операциями. Вот пример для целых чисел без знака:

#include <iostream>
#include <cstdint>

uint32_t bitwise_square(uint32_t n) {
uint32_t square = 0;
for (int i = 0; i < 32; i++) {
if (n & (1 << i)) {
square += (n << i);
}
}
return square;
}

int main() {
uint32_t number = 13;
std::cout << "Bitwise square of " << number << ": " << bitwise_square(number) << std::endl;
return 0;
}

Вывод:

Bitwise square of 13: 169

Чтобы вычислить квадрат без применения умножения, этим методом используется формула (a + b)² = a² + 2ab + b².

Возведение в квадрат в пользовательских системах счисления

Иногда приходится работать с пользовательскими системами счисления или нестандартными представлениями. Вот пример возведения числа в квадрат в формате двоично-десятичного кода:

#include <iostream>
#include <vector>

std::vector<int> bcd_square(const std::vector<int>& bcd) {
std::vector<int> result(bcd.size() * 2, 0);
for (size_t i = 0; i < bcd.size(); ++i) {
for (size_t j = 0; j < bcd.size(); ++j) {
int product = bcd[i] * bcd[j];
int pos = i + j;
result[pos] += product % 10;
result[pos + 1] += product / 10;
}
}
for (size_t i = 0; i < result.size() - 1; ++i) {
result[i + 1] += result[i] / 10;
result[i] %= 10;
}
while (result.size() > 1 && result.back() == 0) {
result.pop_back();
}
return result;
}

void print_bcd(const std::vector<int>& bcd) {
for (auto it = bcd.rbegin(); it != bcd.rend(); ++it) {
std::cout << *it;
}
std::cout << std::endl;
}

int main() {
std::vector<int> number = {5, 2}; // 25 представляется в двоично-десятичЗдесь в квадрат возводится число, представленное в формате двоично-десятичного кода. Это применяется в специализированных сценариях или при взаимодействии с устаревшими системами.ном коде
std::cout << "BCD square of 25: ";
print_bcd(bcd_square(number));
return 0;
}

Вывод:

BCD square of 25: 625

Здесь в квадрат возводится число, представленное в формате двоично-десятичного кода. Это применяется в специализированных сценариях или при взаимодействии с унаследованными системами.

Заключение

На C++ возведение чисел в квадрат  —  это универсальная операция, которой находится самое широкое применение: от элементарной арифметики до сложных математических и научных вычислений.

Благодаря пониманию методов  —  от простого умножения до специализированных алгоритмов для различных представлений чисел  —  эффективно решаются разнообразные задачи возведения в квадрат.

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

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи ryan: Square a Number in C++: Methods and Applications

Предыдущая статья12 бэкенд-концепций, без понимания которых вам не стать старшим разработчиком