rho = 3, theta = 1.5708
rho = 5, theta = 0.643501
Обсуждение
Существует естественная связь между полярными координатами и комплексными числами. Хотя эти понятия в какой-то мере взаимозаменяемы, использование одного и того же типа для представления разных концепций в целом нельзя считать хорошей идеей. Поскольку применение шаблона complexдля представления полярных координат не является элегантным решением, я предусмотрел приведенный в примере 11.25 класс полярных координат, допускающий более естественное применение.
Пример 11.35. Класс полярных координат
#include
#include
using namespace std;
template
struct BasicPolar {
public typedef BasicPolar self;
// конструкторы
BasicPolar() : m() {} BasicPolar(const self& x) : m(x.m) {}
BasicPolar(const T& rho, const T& theta) : m(polar(rho, theta)) {}
// операторы присваивания
self operator-() { return Polar(-m); }
self& operator+=(const self& x) { m += x.m; return *this; }
self& operator-=(const self& x) { m -= x.m; return *this; }
self& operator*=(const self& x) { m *= x.m; return *this; }
self& operator/=(const self& x) { m /= x.m; return *this; }
operator complex() const { return m; }
// открытые функции-члены
T rho() const { return abs(m); }
T theta() const { return arg(m); }
// бинарные операции
friend self operator+(self x, const self& y) { return x += y; }
friend self operator-(self x, const self& y) { return x -= y; }
friend self operator*(self x, const self& y) { return x *= y; }
friend self operator/(self x, const self& y) { return x /= y; }
// операторы сравнения
friend bool operator==(const self& x, const self& y) { return x.m == y.m; }
friend bool operator!=(const self& x, const self& y) { return x.m ! = y.m; }
private:
complex m;
};
typedef BasicPolar Polar;
int main() {
double rho = 3.0; // длина
double theta = 3.141592 / 2; // угол
Polar coord(rho, theta);
cout << "rho = " << coord.rho() << ", theta = " << coord.theta() << endl;
coord += Polar(4.0, 0.0);
cout << "rho = " << coord.rho() << ", theta = " << coord.theta() << endl;
system("pause");
}
В примере 11.35 с помощью typedefя определил тип Polarкак специализацию шаблона BasicPolar. Так удобно определять используемый по умолчанию тип, однако вы можете при необходимости специализировать шаблон BasicPolarдругим числовым типом. Такой подход используется в стандартной библиотеке в отношении классе string, который является специализацией шаблона basic_string.
11.19. Выполнение операций с битовыми наборами
Проблема
Требуется реализовать основные арифметические операции и операции сравнения для набора бит, рассматривая его как двоичное представление целого числа без знака.
Решение
Программный код примера 11.36 содержит функции, которые позволяют выполнять арифметические операции и операции сравнения с шаблоном класса bitsetиз заголовочного файла , рассматривая его как целый тип без знака.
Пример 11.36. bitset_arithmetic.hpp
#include
#include
bool fullAdder(bool b1, bool b2, bool& carry) {
bool sum = (b1 ^ b2) ^ carry;
carry = (b1 && b2) || (b1 && carry) || (b2 && carry);
return sum;
}
bool fullSubtractor(bool b1, bool b2, bool& borrow) {
bool diff;
if (borrow) {
diff = !(b1 ^ b2);
borrow = !b1 || (b1 && b2);
} else {
diff = b1 ^ b2;
borrow = !b1 && b2;
}
return diff;
}
template
bool bitsetLtEq(const std::bitset& x, const std::bitset& y) {
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return false;
if (!x[i] && y[i]) return true;
}
return true;
}
template
bool bitsetLt(const std::bitset& x, const std::bitset& y) {
for (int i=N-1; i >= 0, i--) {
if (x[i] && !y[i]) return false;
if (!x[i] && y[i]) return true;
}
return false;
}
template
bool bitsetGtEq(const std::bitset& x, const std::bitset& y) {
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return true;
if (!x[i] && y[i]) return false;
}
return true;
}
template
bool bitsetGt(const std::bitset& x, const std::bitset& y) {
for (int i=N-1; i >= 0; i--) {
if (x[i] && !y[i]) return true;
if (!x[i] && y[i]) return false;
}
return false;
}
template
void bitsetAdd(std::bitset& x, const std::bitset& y) {
bool carry = false;
for (int i = 0; i < N; i++) {
x[i] = fullAdder(x[i], y[x], carry);
}
}
template
void bitsetSubtract(std::bitset& x, const std::bitset& y) {
bool borrow = false;
for (int i = 0; i < N; i++) {
if (borrow) {
if (x[i]) {
x[i] = y[i];
borrow = y[i];
} else {
x[i] = !y[i];
borrow = true;
}
} else {
if (x[i]) {
x[i] = !y[i];
Читать дальше