Как реализовать класс Decimal для работы с десятичными целыми числами со знаком произвольной длины?
Задание такое: «Создать класс Decimal для работы с десятичными целыми числами со знаком произвольной длины. Число должно быть представлено строкой типа string, каждый символ которой — десятичная цифра, знак стоит слева первым и представлен символами '+' (может отсутствовать) или '-'. Реализовать арифметические операции сложения и вычитания, а также сравнения на равенство и на больше.»
Ответы (1 шт):
Автор решения: Damir Hakimof
→ Ссылка
ДЗ нужно выполнять самому. Я лишь могу представить код, написанный шальной рукой на мутную голову - никаких комментариев нет и гарантий безопасности тоже:
#include <string>
#include <algorithm>
#include <stdexcept>
class Decimal {
private:
std::string value;
bool is_negative = false;
static std::string add_absolute(const std::string& a, const std::string& b) {
std::string result;
int i = a.length() - 1;
int j = b.length() - 1;
int carry = 0;
while (i >= 0 || j >= 0 || carry > 0) {
int digit_a = (i >= 0) ? (a[i--] - '0') : 0;
int digit_b = (j >= 0) ? (b[j--] - '0') : 0;
int sum = digit_a + digit_b + carry;
carry = sum / 10;
result.push_back((sum % 10) + '0');
}
std::reverse(result.begin(), result.end());
return result;
}
static std::string subtract_absolute(const std::string& a, const std::string& b) {
std::string result;
int i = a.length() - 1;
int j = b.length() - 1;
int borrow = 0;
while (i >= 0) {
int digit_a = (a[i] - '0') - borrow;
int digit_b = (j >= 0) ? (b[j] - '0') : 0;
if (digit_a < digit_b) {
digit_a += 10;
borrow = 1;
} else {
borrow = 0;
}
result.push_back((digit_a - digit_b) + '0');
--i;
--j;
}
while (result.size() > 1 && result.back() == '0') {
result.pop_back();
}
std::reverse(result.begin(), result.end());
return result;
}
static bool less_absolute(const std::string& a, const std::string& b) {
if (a.length() != b.length()) {
return a.length() < b.length();
}
return a < b;
}
void normalize() {
size_t non_zero = value.find_first_not_of('0');
if (non_zero == std::string::npos) {
value = "0";
is_negative = false;
return;
}
value = value.substr(non_zero);
if (value == "0") {
is_negative = false;
}
}
public:
Decimal(const std::string& num) {
if (num.empty()) {
throw std::invalid_argument("Empty string");
}
size_t start = 0;
if (num[0] == '+' || num[0] == '-') {
is_negative = (num[0] == '-');
start = 1;
} else {
is_negative = false;
}
if (num.substr(start).empty()) {
throw std::invalid_argument("Invalid number format");
}
for (size_t i = start; i < num.size(); ++i) {
if (!isdigit(num[i])) {
throw std::invalid_argument("Invalid digit in number");
}
}
value = num.substr(start);
normalize();
}
Decimal operator+(const Decimal& other) const {
Decimal result("0");
if (is_negative == other.is_negative) {
result.value = add_absolute(value, other.value);
result.is_negative = is_negative;
} else {
if (less_absolute(value, other.value)) {
result.value = subtract_absolute(other.value, value);
result.is_negative = other.is_negative;
} else {
result.value = subtract_absolute(value, other.value);
result.is_negative = is_negative;
}
}
result.normalize();
return result;
}
Decimal operator-(const Decimal& other) const {
Decimal result("0");
if (is_negative != other.is_negative) {
result.value = add_absolute(value, other.value);
result.is_negative = is_negative;
} else {
if (less_absolute(value, other.value)) {
result.value = subtract_absolute(other.value, value);
result.is_negative = !is_negative;
} else {
result.value = subtract_absolute(value, other.value);
result.is_negative = is_negative;
}
}
result.normalize();
return result;
}
bool operator==(const Decimal& other) const {
return is_negative == other.is_negative && value == other.value;
}
bool operator!=(const Decimal& other) const {
return !(*this == other);
}
bool operator<(const Decimal& other) const {
if (is_negative != other.is_negative) {
return is_negative;
}
if (is_negative) {
return less_absolute(other.value, value);
} else {
return less_absolute(value, other.value);
}
}
bool operator>(const Decimal& other) const {
return other < *this;
}
bool operator<=(const Decimal& other) const {
return !(*this > other);
}
bool operator>=(const Decimal& other) const {
return !(*this < other);
}
std::string toString() const {
return (is_negative ? "-" : "") + value;
}
};