Р. ЛАФОРЕ ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть13) онлайн
Методы
Ниже приводится файл VERYLONG.cpp, содержащий определения методов.
Листинг 13.2. Реализационная часть класса verylong
// verylong.cpp
// реализация обработки данных типа verylong
#include "verylong.h" //заголовочный файл для verylong
//---------------------------------------------------------
void verylong::putvl() const //вывод на экран verylong
{
char temp[SZ];
strcpy(temp,vlstr); //создать копию
cout << strrev(temp); //перевернуть копию
} //и вывести ее
//---------------------------------------------------------
void verylong::getvl() //получить сверхбольшое число от
//пользователя
{
cin >> vlstr; //получить строку от пользователя
vlen = strlen(vlstr); //найти ее длину
strrev(vlstr); //перевернуть ее
}
Листинг 13.2 (продолжение)
//---------------------------------------------------------
verylong verylong::operator + (const verylong v)
//сложение
{
char temp[SZ];
int j;
//найти самое длинное число
int maxlen = (vlen > v.vlen) ? vlen : v.vlen;
int carry = 0; //установить в 1, если сумма >= 10
for(j = 0; j<maxlen; j++) //и так для каждой позиции
{
int d1 = (j > vlen-1) ? 0 : vlstr[j]-'0'; //получить
//разряд
int d2 = (j > v.vlen-1) ? 0 : v.vlstr[j]-'0'; //и еще
int digitsum = d1 + d2 + carry; //сложить разряды
if( digitsum >= 10 ) //если перенос, то
{ digitsum -= 10; carry=1; } //увеличить сумму на 10
else //установить перенос в 1
carry = 0; //иначе перенос = 0
temp[j] = digitsum+'0'; //вставить символ в строку
}
if(carry==1) //если перенос в конце,
temp[j++] = '1'; //последняя цифра = 1
temp[j] = '\0'; //поставить ограничитель строки
return verylong(temp); //вернуть временный verylong
}
//---------------------------------------------------------
verylong verylong::operator * (const verylong v)//умножение
{ //сверхбольших чисел
verylong pprod; //произведение одного разряда
verylong tempsum; //текущая сумма
for(int j=0; j<v.vlen; j++)//для каждого разряда аргумента
{
int digit = v.vlstr[j]-'0'; //получить разряд
pprod = multdigit(digit); //умножить текущий на него
for(int k=0; k<j; k++) //умножить результат на
pprod = mult10(pprod); // степень 10-ти
tempsum = tempsum + pprod; //прибавить произведение к
//текущей сумме
}
return tempsum; //вернуть полученную текущую сумму
}
//---------------------------------------------------------
verylong verylong::mult10(const verylong v) const //умножение аргумента
//на 10
{
char temp[SZ];
for(int j=v.vlen-1; j>=0; j--)//сдвинуться на один разряд
temp[j+1] = v.vlstr[j]; //выше
temp[0] = '0'; //обнулить самый младший разряд
temp[v.vlen+1] = '\0'; //поставить ограничитель строки
return verylong(temp); //вернуть результат
}
//---------------------------------------------------------
verylong verylong::multdigit(const int d2) const
{ //умножение числа на
char temp[SZ]; //аргумент (цифру)
int j, carry = 0;
for(j = 0; j<vlen; j++) //для каждого разряда
{ // в этом сверхбольшом
int d1 = vlstr[j]-'0'; //получить значение разряда
int digitprod = d1 * d2; //умножить на цифру
digitprod += carry; //добавить старый перенос
if( digitprod >= 10 ) //если возник новый перенос,
{
carry = digitprod/10; //переносу присвоить //значение старшего разряда
digitprod -= carry*10; //результату - младшего
}
else
carry = 0; //иначе перенос = 0
temp[j] = digitprod+'0'; //вставить символ в строку
}
if(carry != 0) //если на конце перенос,
temp[j++] = carry+'0'; //это последний разряд
temp[j] = '\0'; //поставить ограничитель
return verylong(temp); //вернуть сверхбольшое число
}
Функции putvl() и getvl() устроены довольно просто. Они используют биб-
лиотечную функцию C под названием strrev() для переворачивания строки, но
вводимые числа отображаются в нормальном порядке.
Перегруженная функция operator+() складывает два числа в формате verylong,
а результат сохраняет в третьем числе. Сложение производится поразрядно.
Оно начинается со сложения нулевого разряда обоих чисел, при необходимости
запоминается перенос. Затем складываются первые разряды, добавляется пере-
нос (если таковой имел место), при необходимости запоминается новый пе-
ренос. Операция продолжается до тех пор, пока не будут сложены все разряды
в большем из двух чисел. Если числа разной длины, недостающие разряды из
меньшего числа устанавливаются в ноль перед их сложением. На рис. 13.3 пока-
зан процесс сложения.
Соответственно, для умножения используется функция operator* (). Она умно-
жает множимое (придется вспомнить давние годы, первые классы школы: множи-
мое — это число, записываемое сверху при умножении «в столбик») на каждый
разряд множителя (множитель — это то, что пишут снизу). Для этого вызывается
функция multdigit(). Затем результат умножается на 10 нужное число раз (для
сдвига окончательного результата на соответствующее число разрядов) с помо-
щью функции mult10(). Итоги этих двух отдельных вычислений складываются
с использованием описанной выше функции operator+().
Для тестирования всего, что было написано выше, можно использовать, напри-
мер, программу FACTOR из главы 3 «Циклы и ветвления». Там мы вычисляли
факториал введенного пользователем числа.
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
