Русская Википедия:Система остаточных классов
Система остаточных классов (СОК) (Шаблон:Lang-en) — система счисления, основанная на модулярной арифметике.
Представление числа в системе остаточных классов основано на понятии вычета и китайской теореме об остатках. СОК определяется набором попарно взаимно простых модулей <math>(m_1,\, m_2,\, \dots,\, m_n)</math>, то есть таких, что <math>\gcd(m_i,\, m_j)=1</math> <math>(i,\, j=0,\, 1,\, \dots,\, n;\ i\neq j)</math>, называемых базисом, и произведением <math>M=m_1\cdot m_2\cdot \ldots \cdot m_n,</math> так, что каждому целому числу <math>x</math> из отрезка <math>[0,\ M-1]</math> ставится в соответствие набор вычетов <math>(x_1,\, x_2,\, \dots,\, x_n)</math>, где
- <math>x_1 \equiv x \pmod{m_1};</math>
- <math>x_2 \equiv x \pmod{m_2};</math>
- <math>\dots\dots\dots\dots\dots\dots\dots</math>
- <math>x_n \equiv x \pmod{m_n}.</math>
При этом китайская теорема об остатках гарантирует однозначность (единственность) представления целых неотрицательных чисел из отрезка <math>[0,\ M-1]</math>.
Преимущества системы остаточных классов
В СОК арифметические операции (сложение, вычитание, умножение, деление) выполняются покомпонентно, если про результат известно, что он является целочисленным и также лежит в <math>[0,M-1]</math>.
Формула для сложения: <math>(x_1, x_2, \dots, x_n) + (y_1, y_2, \dots, y_n) = (z_1, z_2, \dots, z_n)</math>, где
- <math>z_1 \equiv (x_1 + y_1) \pmod{m_1};</math>
- <math>z_2 \equiv (x_2 + y_2) \pmod{m_2};</math>
- <math>\dots\dots\dots\dots\dots\dots\dots\dots\dots</math>
- <math>z_n \equiv (x_n + y_n) \pmod{m_n}.</math>
Аналогично выполняются вычитание, умножение и деление. Замечание: на деление накладываются дополнительные ограничения. Деление должно быть целочисленным, то есть делитель должен нацело делить делимое. Делитель должен быть взаимно простым со всеми модулями базиса.
Недостатки системы остаточных классов
- отсутствие эффективных алгоритмов для сравнения чисел; обычно, сравнение осуществляется через перевод аргументов из СОК в систему счисления (полиадическую) со смешанными основаниями: <math>m_1, m_1 m_2, \dots, m_1 m_2\dots m_{n-1}</math>;
- медленные алгоритмы взаимного преобразования представления чисел из позиционной системы счисления в СОК и обратно;
- сложные алгоритмы деления (когда результат не является целым);
- трудность в обнаружении переполнения.
Применение системы остаточных классов
СОК широко используется в микроэлектронике в специализированных устройствах ЦОС, где требуется:
- контроль за ошибками за счет введения дополнительных избыточных модулей;
- высокая скорость работы, которую обеспечивает параллельная реализация базовых арифметических операций;
- информационная безопасность.
Практическое применение: чехословацкая ламповая ЭВМ «EPOS», советская военная многопроцессорная суперЭВМ 5Э53, предназначенная для решения задач противоракетной обороны.
Специальные системы модулей
В модулярной арифметике существуют специальные наборы модулей, которые позволяют частично нивелировать недостатки и для которых существуют эффективные алгоритмы сравнения чисел и для прямого и обратного перевода модулярных чисел в позиционную систему счисления. Одной из самых популярных систем модулей является набор из трех попарно взаимно простых чисел вида {2n−1, 2n, 2n+1}.
Пример
Рассмотрим СОК с базисом <math>(2;3;5)</math>. В этом базисе можно взаимооднозначно представить числа из промежутка от <math>0</math> до <math>29</math>, так как <math>M = 2\times 3\times 5 = 30</math>. Таблица соответствия чисел из позиционной системы счисления и системы остаточных классов:
<math>0=(0;0;0)</math> | <math>1=(1;1;1)</math> | <math>2=(0;2;2)</math> | <math>3=(1;0;3)</math> | <math>4=(0;1;4)</math> |
<math>5=(1;2;0)</math> | <math>6=(0;0;1)</math> | <math>7=(1;1;2)</math> | <math>8=(0;2;3)</math> | <math>9=(1;0;4)</math> |
<math>10=(0;1;0)</math> | <math>11=(1;2;1)</math> | <math>12=(0;0;2)</math> | <math>13=(1;1;3)</math> | <math>14=(0;2;4)</math> |
<math>15=(1;0;0)</math> | <math>16=(0;1;1)</math> | <math>17=(1;2;2)</math> | <math>18=(0;0;3)</math> | <math>19=(1;1;4)</math> |
<math>20=(0;2;0)</math> | <math>21=(1;0;1)</math> | <math>22=(0;1;2)</math> | <math>23=(1;2;3)</math> | <math>24=(0;0;4)</math> |
<math>25=(1;1;0)</math> | <math>26=(0;2;1)</math> | <math>27=(1;0;2)</math> | <math>28=(0;1;3)</math> | <math>29=(1;2;4)</math> |
Пример сложения
Сложим два числа 9 и 14 в базисе <math>(2;3;5)</math>. Их представление в заданном базисе <math>9=(1;0;4)</math> и <math>14=(0;2;4)</math> (см. таблицу выше). Воспользуемся формулой для сложения: <math>(z_1, z_2, z_3) = (1, 0, 4) + (0, 2, 4)</math>
- <math>z_1 \equiv (x_1 + y_1) \pmod{m_1} \equiv (1 + 0) \pmod{2} = 1;</math>
- <math>z_2 \equiv (x_2 + y_2) \pmod{m_2} \equiv (0 + 2) \pmod{3} = 2;</math>
- <math>z_3 \equiv (x_3 + y_3) \pmod{m_3} \equiv (4 + 4) \pmod{5} = 3;</math>
<math>(z_1, z_2, z_3) = (1, 2, 3)</math> — по таблице убеждаемся, что результат равен 23.
Пример умножения
Умножим два числа 4 и 5 в базисе <math>(2;3;5)</math>. Их представление в заданном базисе <math>4=(0;1;4)</math> и <math>5=(1;2;0)</math> (см. табличку выше). Воспользуемся формулой для умножения: <math>(z_1, z_2, z_3) = (0, 1, 4) * (1, 2, 0)</math>
- <math>z_1 \equiv (x_1 * y_1) \pmod{m_1} \equiv (0 * 1) \pmod{2} = 0;</math>
- <math>z_2 \equiv (x_2 * y_2) \pmod{m_2} \equiv (1 * 2) \pmod{3} = 2;</math>
- <math>z_3 \equiv (x_3 * y_3) \pmod{m_3} \equiv (4 * 0) \pmod{5} = 0;</math>
<math>(z_1, z_2, z_3) = (0, 2, 0)</math> — по таблице убеждаемся, что результат равен 20.
Замечание: если бы мы умножали или складывали числа, которые дали в результате умножения число больше или равное <math>M = 30</math>, то полученный результат <math>RES \equiv REAL \pmod{M}</math>, где <math>REAL</math> — результат операции в позиционной системе счисления.
Пример деления, при условии, что возможно деление нацело
Деление может быть выполнено аналогично умножению, но только если делитель делит делимое нацело, без остатка.
Для модулей <math>(29;31;32)</math> разделим число 1872 на 9.
Делим <math>1872=(16;12;16)</math> на <math>9=(9;9;9)</math>.
Воспользуемся формулой
<math>z_i \equiv (x_i * y_i^{-1}) \pmod{m_i}.</math>
Здесь надо сказать, что <math>y_i^{-1}*y_i=1 \pmod{m_i}</math>, что не то же самое, что просто разделить <math>x</math> на <math>y</math>.
По формуле <math>y_i^{m_i-1}=1 \pmod{m_i}</math> получаем:
<math>9^{29-2} \pmod{29} = 13,</math>
<math>9^{31-2} \pmod{31} = 7.</math>
<math>9^{32-2} \pmod{32} = 17;</math>
<math>z_1 \equiv (16*13) \pmod{29} = 5,</math>
<math>z_2 \equiv (12*7) \pmod{31} = 22,</math>
<math>z_3 \equiv (16*17) \pmod{32} = 16.</math>
Это и есть правильный результат — число 208. Однако такой результат можно получить, только если известно, что деление производится без остатка.
См. также
Литература
- Шаблон:Книга
- Шаблон:Книга
- Шаблон:Книга
- Шаблон:Source
- Шаблон:Книга
- Шаблон:Книга
- Шаблон:Книга
- Шаблон:Книга
- Шаблон:Книга
Ссылки