Читаю книжку Бениаминов Е.М., Ефимова Е.А. Элементы универсальной алгебры и ее приложений в информатике.
По окончании 1 главы есть задачи и упражнения, номер 1.8. (стр 22)
'Опишите тип данных "Двоичные числа" с операцией сложения двоичных чисел'
Думаю так:
По определению - тип данных это тройка <Имя, Cигнатура, Mножество определяющих соотношений> (стр 17).
Сигнатура - это пара <Множество имен носителей, Множество имен типизированных операций> (стр 14, но множество отношений пусто, поэтому его не пишу).
запишу формально:
Код:
<
Имя: Тип_Двоичные_числа,
Cигнатура:
<
Множество имен носителей: {Двоичное_число}
Множество имен типизированных операций:{Сложение: Двоичное_число X Двоичное_число -> Двоичное_число}
>
Множество определяющих соотношений: ???
>
Двоичное число можно кодировать как сетку 2-цифр по 2-разрядам, примерно так
Код:
... ц ц ц ц ц ц ц, ц ц ц ц ... цифры
... 6 5 4 3 2 1 0 -1 -2 -3 -4 ... разряды
и еще надо добавить знак +-
получается, что двоичное число - это знак +- и бесконечная совокупнось пар <2-цифра, 2-разряд>, где 2-разряд - это целое, 2-цифра - это "0" или "1". Вычислить значение числа можно как сумму тех разрядов, которым соответствует цифра "1".
Сложение. Думаю складывать в столбик(по другому не умею). Тогда надо сделать следующее:
1. для двух чисел, уметь сопоставлять их друг с другом так, чтобы можно было для заданного разряда выделять соответствующие ему цифры в одном и другом числе (это просто)
2. уметь складывать 2 одноцифровых числа (тут таблица сложения поможет)
3. уметь учитывать остаток от предыдущего действия на следующий разряд, тоесть, уметь складавать по 3 одноцифровых числа, это несложно по рекурсии
4. уметь для заданного разряда получать следующий разряд (это просто)
5. так как такое сложение - "однопроходное" и цифры результата в бОльших разрядах зависят от цифр операндов в меньших - то надо найти разряд, с которого можно такое сложение начинать. Это должен быть такой разряд, меньше которого нет разрядов с цифрой "1" (они будут влиять). В моем кодировании такого разряда выделить нельзя, разряды вправо уходят в -беск. Значит такое кодирование не совместимо с таким сложением. Хек приплыли. Надо другое кодирование или другой способ сложения
Начинаю думать что поторопился с трактовкой "Двоичного числа". Наверное автор имел ввиду "целое двоичное число" а у меня - действительное. В принципе, если будет тип данных для целого - то из него можно легко сконструировать и рациональное и комплексное. Но действительное - аж затрудняюсь.
теперь взял бумажку и ручку и составил для натуральных с нулем, вот что получилось:
--------------------------
Код:
Bins:
носитель: множество слов на алфавите {0,1}
отображения:
{
_0: ->Bins,
_1: ->Bins,
C:Bins x Bins -> Bins,
Add:Bins x Bins -> Bins
}
соотношения:
{
//выделение цифры 0
_0=0
//выделение цифры 1
_1=1
//конкатенация с нулем
C(x,_0) = x0
//конкатенация с единицей
C(x,_1) = x1
//коммутативность явно, чтобы последующие соотношения не дублировать по 2 раза
Add(x,y) = Add(y,x)
//для простых операндов
Add(_0, _0) = _0
Add(_1, _0) = _1
Add(_1, _1) = C(_1, _0)
//один из операндов составной
Add(C(x,_0), _0) = C(x,_0)
Add(C(x,_1), _0) = C(x,_1)
Add(C(x,_0), _1) = C(x,_1)
Add(C(x,_1), _1) = C(Add(x,_1),_0)
//оба составные
Add(C(x,_0), C(y,_0)) = C(Add(x,y),_0)
//Add(C(x,_1), C(y,_0)) = C(Add(x,y),_1) по комутации эквивалентно следующему, можно не писать
Add(C(x,_0), C(y,_1)) = C(Add(x,y),_1)
Add(C(x,_1), C(y,_1)) = C(Add(Add(x,y),_1),_0)
}
проверка
111 + 1 =
Add(C(C(_1,_1),_1), _1) =
C(Add(C(_1,_1), _1), _0) =
C(C(Add(_1,_1),_0), _0) =
C(C(C(_1, _0),_0), _0) =
1000
все.
-------------------------
на мой взгяд правильно, хоть и с некоторыми вольностями в формализации
такие "натуральные с нулем" несложно довести до целых, и далее до рациональных и комплексных.
Но остается вопрос чести: как быть с действительными числами?