В примере 11.35 с помощью typedef
я определил тип Polar
как специализацию шаблона BasicPolar
. Так удобно определять используемый по умолчанию тип, однако вы можете при необходимости специализировать шаблон BasicPolar
другим числовым типом. Такой подход используется в стандартной библиотеке в отношении классе string
, который является специализацией шаблона basic_string
.
11.19. Выполнение операций с битовыми наборами
Требуется реализовать основные арифметические операции и операции сравнения для набора бит, рассматривая его как двоичное представление целого числа без знака.
Программный код примера 11.36 содержит функции, которые позволяют выполнять арифметические операции и операции сравнения с шаблоном класса bitset
из заголовочного файла
, рассматривая его как целый тип без знака.
#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
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
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
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
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
bool carry = false;
for (int i = 0; i < N; i++) {
x[i] = fullAdder(x[i], y[x], carry);
}
}
template
void bitsetSubtract(std::bitset
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];
borrow = false;
} else {
x[i] = y[i];
borrow = y[i];
}
}
}
}
template
void bitsetMultiply(std::bitset
std::bitset
x.reset();
// мы хотим минимизировать количество операций сдвига и сложения
if (tmp.count() < y.count()) {
for (int i=0; i < N; i++) if (tmp[i]) bitsetAdd(x, у << i);
} else {
for (int i=0; i < N; i++) if (y[i]) bitsetAdd(x, tmp << i);
}
}
template
void bitsetDivide(std::bitset
std::bitset
if (y.none()) {
throw std::domain_error("division by zero undefined");
}
q.reset();
r.reset();
if (x.none()) {
return;
}
if (x == y) {
q[0] = 1;
return;
}