#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
//Числа хранятся в формате "младший разряд первым",
//Поддержка отрицательных чисел отсутствует
//Минимальный размер выделяемой памяти под хранение BCD числа
#define MINBCDSIZE 4
// Класс BCD-числа
class LongBCD
{
private:
char * data; // BCD-число
int size; // Его размер
// Функция увеличения области данных с их сохранением
void extend(int newsize)
{
char *nd = new char [newsize];
memset(nd, '0', newsize);
memcpy(nd, data, size);
size = newsize;
delete data;
data = nd;
}
// Установка значения i-го разряда области данных BCD-числа
void set(int i, char dig)
{
if (i >= size)
extend(i + 1);
data[i] = dig;
}
// Обнуление области данных BCD-числа, начиная с i-го разряда
void zero(int i);
// Установка значения BCD-числа на основании другого BCD-числа
void setvalue(LongBCD & n);
// Суммирование (+=)
void add(LongBCD & n);
// Вычитание (-=)
void sub(LongBCD & n);
public:
// Конструкторы
LongBCD();
LongBCD(long n);
// Деструктор
~LongBCD() {if (data) free(data);}
// Установка значения BCD-числа на основании long
void setvalue(long n);
// Перегрузка оператора присваивания
LongBCD & operator = (long n) {setvalue(n); return *this;}
LongBCD & operator = (LongBCD & n) {setvalue(n); return *this;}
// Перегрузка операций + и -
friend LongBCD operator + (LongBCD &, LongBCD &);
friend LongBCD operator - (LongBCD &, LongBCD &);
// Функция вывода BCD-числа на экран
void show(void);
};
// Суммирование (+=)
void LongBCD::add(LongBCD & n)
{
int maxl = n.size;
int i, carry = 0;
// Проверка наличия достаточного количества памяти
if (maxl >= size) extend(maxl + 1);
// Цикл по всем разрядам, начиная с младшего
for (i = 0; i < maxl; i++)
{
int res = (data[i] - '0') + (n.data[i] - '0') + carry;
// Учет переноса
if (res > 9)
{
res -= 10;
carry = 1;
}
else carry = 0;
set(i, '0' + res);
}
if (carry) set(maxl, '1');
}
// Вычитание (-=)
void LongBCD::sub(LongBCD & n)
{
int maxl = n.size;
int i, carry = 0;
// Проверка наличия достаточного количества памяти
if (maxl >= size) extend(maxl + 1);
// Цикл по всем разрядам, начиная с младшего
for (i = 0; i < maxl; i++)
{
int res = (data[i] - '0') - (n.data[i] - '0') - carry;
// Учет заема
if (res < 0)
{
res += 10;
carry = 1;
}
else carry = 0;
set(i, '0' + res);
}
}
// Обнуление области данных BCD-числа, начиная с i-го разряда
void LongBCD::zero(int i)
{
while(i < size) data[i++] = '0';
}
// Установка значения BCD-числа на основании long
void LongBCD::setvalue(long n)
{
int i = 0;
while (n != 0)
{
set(i, '0' + (n % 10));
n /= 10;
i++;
}
zero(i);
}
// Установка значения BCD-числа на основании другого BCD-числа
void LongBCD::setvalue(LongBCD & n)
{
int i;
for (i = 0; i < n.size; i++) set(i, n.data[i]);
zero(i);
}
// Функция вывода BCD-числа на экран
void LongBCD::show(void)
{
int i = size;
while((i != 0) && (data[i-1] == '0')) i--;
if (i == 0)
putchar('0');
else
while (i != 0) {
i--;
putchar(data[i]);
}
puts("");
}
// Конструктор создает число со значеним 0
LongBCD::LongBCD()
{
data = new char[MINBCDSIZE];
size = MINBCDSIZE;
zero(0);
}
// Конструктор создает число со значеним, определяемым переменной
LongBCD::LongBCD(long n)
{
data = new char[MINBCDSIZE];
size = MINBCDSIZE;
setvalue(n);
}
// Перегрузка операции +
LongBCD operator + (LongBCD & a, LongBCD & b)
{
LongBCD * temp = new LongBCD;
*temp = a;
temp->add(b);
return * temp;
}
// Перегрузка операции -
LongBCD operator - (LongBCD & a, LongBCD & b)
{
LongBCD * temp = new LongBCD;
*temp = a;
temp->sub(b);
return * temp;
}
void main(void)
{
clrscr();
LongBCD A, B, C;
long temp;
cout << "Введите BCD-число A: ";
cin >> temp;
A.setvalue(temp);
cout << "Введите BCD-число B: ";
cin >> temp;
B.setvalue(temp);
cout << "\nA = "; A.show();
cout << "\nB = "; B.show();
cout << "\nA+B = "; C=A+B; C.show();
cout << "\nA-B = "; C=A-B; C.show();
getch();
}