Шумеро-вавилонские клинописные глиняные таблички из Месопотамии содержат древнейшие известные математические тексты. Некоторым из них по пять тысяч лет и более.

Шумеро-вавилонская клинописная цифра 42 выглядит так: {??}. И это именно цифра, которой может соответствовать и число 42_{10}, и 2520_{10}, и 151200_{10} и так далее, по степеням 60. В том числе, по обратным степеням, например: \frac{42}{60_{10}}, \frac{42}{3600_{10}}.

Шрифты и клинопись

Если в этом тексте через веб не отображается клинопись, то это из-за отсутствия шрифтов; добавьте шрифты с клинописным блоком, cuneiform; например - Noto.

В шумеро-вавилонской Месопотамии использовали шестидесятеричную систему. То есть, позиционную систему по основанию шестьдесят: каждой позиции соответствует количество единиц, умноженное на степень 60, веса по позициям суммируются. Обычный способ. Поскольку основание 60_{10}, то нужно 59 цифр. Откуда и цифра 42 (конечно, 42 тут - это условное обозначение, поэтому к нему даже можно не приписывать нижний индекс _{10}). В клинописной записи отдельных цифр вертикальные «палки» обозначают единицы, если их количество не превышает 9, а «галки» - обозначают десятки, что, впрочем, не делает систему десятеричной.

Вообще, древнейшние шумерские системы счисления использовали для записи цифр круги и «полуовалы». «Галки» и «палки» появились позднее, когда система стала логически стройнее. К тому же, протоклинописных кругов и «полуовалов» всё ещё нет в Unicode. При этом, в самых древних шумерских вариантах интерпретация цифр зависела ещё и от того, что именно подсчитывается: использовался ли знак для обозначения мер зерновых, для записи количества кувшинов масла или площади земельного надела - числовое значение могло быть разным. Это в точности современный Javascript, неявно преобразующий строку в числовой тип.

Преобразование типов и пиво

Это эквивалентные операции, не сомневайтесь. Многие неотъемлемые части информационных технологий очень древние. Предположим, что неявное преобразование типов приводит ASCII-код записи "42" в значение целочисленного типа 42. Это означает, что последовательность байтов 0x3432, превращается в 0x2A. Но парой байтов были обозначены ASCII-символы. У древнейших шумер были бы, предположим, кувшины с пивом, а не ASCII-символы. Не удивительно, что эффект был позднее исправлен (не в Javascript, который хорош и без пива).

Шумеро-вавилонская система счисления имеет целый ряд особенностей. Например, способ записи не подразумевал явного обозначения степени конкретной позиции: сколько там весит единица - 60, 60^{3} - всё определялось контекстом. Таким образом, это древнейшая система с плавающей точкой! И она на несколько тысяч лет старше всем привычных float, double, как и современных стандартов «плавающей точки» вообще. Впрочем, если в современных стандартах бывает два нуля, - вообще говоря, не равных друг другу, - то в шумеро-вавилонской системе настоящего нуля, как такового, вообще не было, хоть в поздних вариантах и появился знак для заполнения пустых разрядов.

Выбор числа 60_{10} в качестве основания имеет арифметическое обоснование. У шестидесятеричной системы большое преимущество, если сранивать, например, с десятеричной, а тем более - с двоичной, восьмеричной и шестнадцатеричной. Всё потому, что число шестьдесят - «очень непростое»: 60 = 2^{2} * 3 * 5. Арифметика записи по основанию шестьдесят оказывается удобной для учёта привычных долей - можно самые ходовые доли записать точно: \frac{1}{2}, \frac{1}{3}, \frac{1}{4}, \frac{1}{5}, \frac{1}{6}, \frac{1}{10}, \frac{1}{12}, \frac{1}{15}, \frac{1}{20}, \frac{1}{30}.

Итак, разберёмся с шумерскими цифрами. Цифрами служили комбинации клинописных знаков. Мы уже назвали их «галки» и «палки», соответственно внешнего вида в Unicode и на табличках. {?} - это "галка", которая соответствует десяти единицам; {?} - это «палка», которая соответствует единице. Единицы в количестве менее десяти записывались в виде плотного набора «палок»: {?} - это семь. {??} - это цифра, которой в единицах соответствует число 23_{10}. «Галки» повторялись кратно десяти.

В зависимости от позиции и от контекста цифра 23 может обозначать единицы, то есть нулевую степень основания 60_{10}, или единицы при 60^{1}, или единицы при 60^{2} = 3600. Соответственно, {??} (23) в позиции единиц - это 23_{10}. {??} в позиции 60^{1} это 23_{10} *  60_{10} = 1380_{10}. А для второй степени: 23_{10}  * {60_{10}}^{2} = 82800_{10}.

Позиции разделялись пробелами, что не всегда однозначно, так как нуля в классическом варианте не было. {?}\quad{??} это, например, 2*{60_{10}}^{1} + 13_{10} = 133_{10}. Почему "например"? Потому что это система с плавающей точкой. {?}\quad{??} с тем же успехом можно интерпретировать как 2_{10} + \frac{13}{60_{10}}.

Эта особенность сильно помогает при практических вычислениях, но мешает при считывании результата спустя всего лишь три-четыре тысячи лет. Всё достаточно просто. Различать клинья на реальных табличках трудно, но не схему записи.

Использование шумерской шестидесятеричной системы счисления в точности являлось прикладным случаем того, что сейчас принято называть «компьютерными науками» (computer science). Поэтому очень полезен сравнительный взгляд, учитывающий другие позиционные системы счисления, используемые в информатике и в тех самых компьютерных науках сейчас.

Старинная шутка гласит, что типов людей всего 10 - одни уже знают двоичную систему счисления, а другие - ещё нет. Система счисления - это способ записи чисел. Разные системы хорошо подходят для разных целей. Так, двоичная система подходит не только для записи шуток (10_{2} = 2_{10}), но и служит неплохим математическим фундаментом «железячных» компьютерных вычислений: компьютеры, как известно, не считают, а переключают транзисторные «флип-флопы». Успешная интерпретация таких переключений возможна только потому, что есть двоичная система счисления.

Использование систем счисления с разными основаниями является привычной практикой: кроме двоичной и десятичной, распространены восьмеричная и шестнадцатеричная. Восьмеричная система, конечно, встречается нынче реже, чем шестнадцатеричная, но всё равно постоянно присутствует рядом с вами, если вы сетевой инженер или разработчик системного ПО. Например, один из штатных способов записи IP-адреса, при вызове тех или иных утилит, использует восьмеричную систему, вот так: 010.010.010.010 - это будет 8.8.8.8 в привычной форме по основанию 10 (десять). Согласно древнему соглашению, октет IPv4-адреса, начинающийся с нуля, интерпретируется как записанный в восьмеричной системе. На табличках из Месопотамии об этом ничего не сказано, но, из-за базовых unix-библиотек, такое преобразование сейчас касается не только октетов.

А вот шестнадцатеричная система вряд ли нуждается в примерах: этот вариант встречается в практике программирования почти столь же часто, как и система десятичная. И не только в программировании. На стороне веб-фронтендеров в шестнадцатеричной системе повсеместно записываются цвета внутри каскадных таблиц стилей (CSS) - загляните хоть бы и в исходный код веб-страниц «Хабра». По основанию 16_{10} очень удобно записывать байтовые маски: запись получается не такой длинной, как в двоичной, а один октет укладывается в две цифры.

Более того, каждую шестнадцатеричную цифру полубайта можно выкинуть на четырёх пальцах руки, перпендикулярных большому пальцу: 0xF - всё четыре пальца. 0x8 - указательный или мизинец, в зависимости от того, «тупоконечные» у вас пальцы или «остроконечные». Не в смысле формы, а в смысле, с какой стороны старший бит байта. При работе с древними компьютерами (не глиняными, но примерно того же поколения) правильная шестнадцатеричная распальцовка сильно ускоряла набор на битовых переключателях. Нынче навык сей доступен разве что редкому динозавру-технарю, да и не так полезен, однако верная распальцовка всё ещё может быть эффективно использована в беседе с молодыми DevOps, для пущего их убеждения.

Не факт, что старшинство указательного пальца, взятое по модулю «хиральности» (правой/левой руки), оказало влияние на развитие систем счисления. Но вполне возможно, что принцип счёта по трём фалангам каждого из четырёх пальцев прямо связан с двенадцатеричными системами, которые мы здесь не рассматриваем. Впрочем, как раз 12_{10} * 5_{10} = 60_{10}.

Выше мы заметили, что основание 60 позволяет едва ли не каждую привычную на практике долю записать точно. Благодаря этой возможности шестидесятеричная система превосходит десятеричную и другие системы. Разберёмся, что именно тут имеется в виду.

Всякую позиционную систему счисления можно использовать для записи дробей: возьмём обратные степени основания {-1, -2, -3...} и станем записывать дробную часть, отделив её от целой каким-нибудь знаком. Точкой, например. Это уже было проделано выше. Для десяти - получаем всем привычные десятичные дроби: 0.4242. Точно так же будут работать и двоичная, и восьмеричная, и шестнадцатеричная система. Нет разницы. Только вот с записью долей таким способом возникнет сложность иного рода: запись окажется «бесконечной вправо» (ну, если записывать числа и расставлять веса справа налево; «бесконечная влево» запись - это p-адические числа, другая тема, хоть и неожиданно близкая).

Так, 16 - это 2^{4}. То есть, основание шестнадцатеричной системы, при всём богатстве выбора, какое-то слишком "простое", и проблемы начнутся с нечётными знаменателями в долях вида \frac{a}{b}.

Например, \frac{1}{5} = 0.33(3)_{16} - всё в шестнадцатеричной системе, а тройка здесь - в периоде (обозначается скобками). «В периоде» - это значит, что развернутая запись никогда не окончится. Однако в десятичной записи \frac{1}{5} = 0.2_{10}. «Периода» нет, запись терминируется тут же. И это одно и то же рациональное число - одна пятая.

Да, формально, и 0.33(3)_{16}, благодаря возможности обозначить «периодические цифры», - это точная конечная запись для \frac{1}{5}. Да, к 0.2_{10}, если уж быть максимально строгим, должен быть приписан бесконечный хвост нулей - 0.2(0), но его принято не указывать (да вообще мало кто помнит, что он там есть, но его не видно; как и про второе представление с бесконечно повторяющимися девятками, для десятичной системы). Это всё так по определению, а требуется по тем же причинам, по которым в десятеричной (десятичной) системе 0.9(9)_{10} = 1.

Казалось бы, сложно ли записать (3) как период? Всего лишь скобки. Однако проблема в том, что длина периодической части может быть произвольной, не обязательно лишь одна цифра повторяется.

Заметьте, что 0.3_{16} * 5 = 0.F_{16}. Аналогично тому, как 0.3_{10} * 3_{10} = 0.9_{10}. Но почему в десятичной системе \frac{1}{5} = 0.2? Потому что 10_{10} = 2*5. Соответственно, все числа, представимые в виде 2^{n} * 5^{m}, будут регулярными в десятичной системе: «обратные» к ним можно записать в виде конечной дроби. Шестнадцатеричная же система имеет основание 2^{4}, а число 5 нельзя представить в виде 2^{n}, отсюда и десятичная часть в периоде.

По тем же причинам и 1/7_{16} = 0.249(249)_{16}. Три цифры период.

А вот для (\frac{1}{7^{11}})_{16} период записи после запятой составит 847425747 шестнадцатеричных цифр (проверьте на калькуляторе). Так что проблема точной записи, даже если позволяется вводить дополнительную структуру и указывать «период» в скобках, - остаётся. Кстати, поскольку в разложении 10 есть 2, то найти столь же иллюстративный обратный пример - число, которое «хорошо» представляется в десятичной системе, но «плохо» в шестнадцатеричной, - не выйдет.

Будем обозначать клинописные цифры десятичной записью соответствующего числа, разделять цифры будем запятой «,», а точку-разделитель целой и дробной части (мантиссы) - обозначим точкой с запятой («;»). Это общепринятый сейчас способ. Тогда \frac{1}{7} в шестидесятеричной шумеро-вавилонской системе это 0; 8,34,17(,8,34,17) или, если клинописью, {?}\quad{??}\quad{??}\quad({?}\quad{??}\quad{??})... (сила Unicode; которая хороша там, где реально требуется).

А что ещё за «обратные»? Например, в десятеричной системе деление на два эквивалентно умножению на пять с последующим сдвигом десятичной точки. Элементарный пример: 7/2 = (7 * 5)/10_{10} = 35_{10}/10_{10} = 3.5_{10}. В шестидесятеричной системе основание делится не только на 2 и 5, но ещё и на 3. В шестидесятеричной системе регулярные числа - это все те, которые представимы в виде 2^{n} * 3^{l} * 5^{m}. Здесь много делителей: [1, 2, 3, 4, 5, 6, 10_{10}, 12_{10}, 15_{10}, 20_{10}, 30_{10}, 60_{10}]. Поэтому больше долей записываются точно.

В древней шумеро-вавилонской практической арифметике деление одного числа на другое выполняется с помощью специальных таблиц. Чтобы найти \frac{A}{B}, древний инженер-информатик берёт «таблицу обратных» и находит число, обратное к B. Обратите внимание, что это не совсем те обратные, не совсем \frac{1}{B} - обратное здесь берётся по основанию системы счисления. Так, в десятеричном примере выше (\frac{7}{2}), обратное к \frac{1}{2} - это 5. Почему? Потому что 5 * 2 = 10_{10}, то есть \frac{2}{10} при умножении на 5 дают единицу.

Если принять плавающую точку, то 1 в нулевом разряде, если сдвинуть точку вправо, даст 10_{10} и т.д. Поэтому, в десятеричном примере, определив обратное 5, нужно посмотреть в таблицу умножения, найти там 5*7 = 35_{10}, выписать ответ и не забыть сдвинуть десятичную точку: 3.5_{10}. Так что именно плавающая точка позволяет нормировать имеющиеся числа, приводя их к удобной для вычислений форме записи. Умение работать с такими таблицами очень актуально, ведь в древней Месопотамии нет даже механических арифмометров (ну, скорее всего, их либо нет, либо они слишком дорого стоят). А вот глиняные таблички умножения и взятия обратных для шестидесятеричной системы есть.

Разделим 10,30 на 1,15. Это шумерские цифры. То есть, 10,30 = 630_{10}, а 1,15 = 75_{10}. Найдём обратный к 1,15 - это 48, потому что 1,15 * 48 = 1 (то есть, 3600_{10}). Найдём результат умножения 48 на 10,30. Это 8,24 (а нуля у нас нет - не забывайте). Поставим «плавующую точку» на место и вот результат: 8; 24.

То же самое в клинописных цифрах, как это делал бы инженер-информатик в Месопотамии несколько тысяч лет назад, превращая LaTeX в засечки на глине:

\frac{{?}\quad{?}}{{?}\quad{?}{?}} (здесь черта - знак деления),

обратный: {??}, умножаем по таблице:{??} * {?}\quad{?}.

Результат: {?}\qquad{??} - и через те самые несколько тысяч лет придётся догадываться, где же здесь стоит плавающая точка.

Чуть выше мы нашли, что 1/7 в шумеро-вавилонской системе не представляется точно, потому что запись будет бесконечной: {?}\quad{??}\quad{??}\quad({?}\quad{??}\quad{??}).... Так происходит потому, что 7 - взаимно простое с основанием 60_{10}. Скорее всего, для древнего шумерского инженера-информатика рациональное число \frac{1}{7} не было бы «рациональным», в том смысле, что такую долю невозможно записать точно в шестидесятеричной системе, а в точных таблицах нет обратного значения. Непонятно, как считать, поэтому \frac{1}{7} не должна встречаться на практике. Конечно, если \frac{1}{7} всё же встретилась, то инженеру-информатику пришлось бы воспользоваться таблицами «приближённых» значений, подобрав подходящий интервал. Такие таблицы тоже имелись, но их наверняка старались избегать, ведь иначе шестидесятеричная система оказывается избыточной.

Литература

  • Knuth, D., 1972. Ancient Babylonian Algorithms. Commun. ACM 15 (7)

  • Daniel F. Mansfield, N.J. Wildberger. Plimpton 322 is Babylonian Exact Sexagesimal Trigonometry

Комментарии (8)


  1. OldCoder
    04.07.2025 20:42

    Наверно 0.9(9)_{10} = 1 это ошибка. Должно быть 1/9*9 = 1 ?


    1. vened Автор
      04.07.2025 20:42

      Имеется в виду, что 0.99999... - это и есть вторая запись 1.


  1. Jijiki
    04.07.2025 20:42

    я подумал о египетских пирамидах ))


    1. Jijiki
      04.07.2025 20:42

      проверил многое столбиком было интересно ) ух спасибо )

      с числами точно есть нюансы какие-то как-раз наверно из-за битности


      1. vened Автор
        04.07.2025 20:42

        Да, по основанию 2 - "разбегаться" цифры будут иначе.


  1. ru_vlad
    04.07.2025 20:42

    К сожалению в моем браузере (FireFox) шумерские обозначения не отобразились.


    1. vened Автор
      04.07.2025 20:42

      Это, скорее всего, из-за неполных шрифтов. Нередкая ситуация, к сожалению - далеко не все блоки Unicode есть в доступных шрифтах. Я поэтому специально обернул все шумерские цифры статьи в LaTeX-выражения, как формулы, чтобы они рендерились отдельно в SVG. Видимо, это не очень-то помогло.


    1. ssj100
      04.07.2025 20:42

      ... любое упоминание о <данные удалены> будут стерты с носителя...