Самьюэл Алекс
Шрифт:
printf("%u\n", number_to_unsigned_int(answer));
destroy_number(answer);
clear_stack(&number_stack);
}
}
return 0;
}
Функции, приведенные в листинге А.4 выполняют операции над унарными числами, представленными в виде связных списков.
Листинг А.4. (number.c) Арифметика унарных чисел
/* Операции над унарными числами */
#include <assert.h>
#include <stdlib.h>
#include <limits.h>
#include "definitions.h"
/* Создание числа, равного нулю. */
number make_zero {
return 0;
}
/* Эта функция возвращает ненулевое значение,
если аргумент равен нулю. */
int zerop(number n) {
return n == 0;
}
/* Уменьшение числа на единицу. */
number decrement_number(number n) {
number answer;
assert(!zerop(n));
answer = n->one_less_;
free(n);
return answer;
}
/* Добавление единицы к числу. */
number add_one(number n) {
number answer = malloc(sizeof(struct LinkedListNumber));
answer->one_less_ = n;
return answer;
}
/* Удаление числа. */
void destroy_number(number n) {
while (!zerop(n))
n = decrement_number(n);
}
/* Копирование числа. Эта функция необходима для того,
чтобы при временных вычислениях не искажались
исходные операнды. */
number copy_number(number n) {
number answer = make_zero;
while (!zerop(n)) {
answer = add_one(answer);
n = n->one_less_;
}
return answer;
}
/* Сложение двух чисел. */
number add(number n1, number n2) {
number answer = copy_number(n2);
number addend = n1;
while(!zerop(addend)) {
answer = add_one(answer);
addend = addend->one_less_;
}
return answer;
}
/* Вычитание одного числа из другого. */
number subtract(number n1, number n2) {
number answer = copy_number(n1);
number subtrahend = n2;
while(!zerop(subtrahend)) {
assert(!zerop(answer));
answer = decrement_number(answer);
subtrahend = subtrahend->one_less_;
}
return answer;
}
/* Умножение двух чисел. */
number product(number n1, number n2) {
number answer = make_zero;
number multiplicand = n1;
while (!zerop(multiplicand)) {
number answer2 = add(answer, n2);
destroy_number(answer);
answer = answer2;
multiplicand = multiplicand >one_less_;
}
return answer;
}
/* Эта функция возвращает ненулевое значение, если
ее аргумент является четным числом. */
number even(number n) {