Дистрибутивность умножения относительно сложения означает, что a*(b + c) = a*b + a*c. В действительных числах, по определению, умножение дистрибутивно относительно сложения. Запишем это на Pyhton и посмотрим, что напечатает простая программа.

import math

q = 11*(math.sqrt(5) + math.sqrt(17))    # q = a*(b + c)
p = 11*math.sqrt(5) + 11*math.sqrt(17)   # p = a*b + a*c
print(p == q)                            # q == p => (q - p) == 0

q = 34*(math.sqrt(5) + math.sqrt(17))
p = 34*math.sqrt(5) + 34*math.sqrt(17)
print(p == q)                            # ???

Запускаем (Python 3.11.2) и смотрим:

True
False

В коде, в первом случае, написано:

p = 11*(√5 + √17),
q = 11*√5 + 11*√17.

Значения p, q сравниваются. Программа выводит True – значения равны. Что и следовало ожидать, если бы это были действительные числа: по определению, q и p – это одно и то же число.

Во втором случае написано всё то же самое, алгебраически, но другой множитель:

p = 34*(√5 + √17),
q = 34*√5 + 34*√17.

Удивительно, но результат сравнения p и q теперь False – числа не равны.

Да, конечно, причина в представлении типа float в компьютерной памяти: для 34 порядок округления сыграл свою роль – результаты разошлись в одном разряде. Обычно полагают, что этот пример лишь показывает ограничения битового представления float (и других типов). Но вообще-то основной вывод тут должен быть другим: для float не выполняется дистрибутивность умножения. То есть, операции с float – это операции с float, а не операции с числами, тем более, с действительными.

Компьютеры не работают с действительными числами. Потому что это невозможно. Да, натуральные, целые, рациональные – это подмножества действительных (с которыми подмножествами компьютеры тоже не работают, кстати). Но если вы случайным образом бросите точку на числовую прямую, то попадёте в иррациональное число. Запись этого числа в виде десятичной дроби – бесконечный процесс, который, впрочем, может быть формально определён – получится алгоритм вычисления конкретной записи числа (вспомним формулы для π, например).

Однако действительных чисел, которые для записи требуют выполнения бесконечного процесса, несравнимо больше, чем всех возможных записей алгоритмов, потому что множество записей алгоритмов – счётно. То есть, если вы действительно поверили в вещественные числа (каламбур), то возможных задач для решения на компьютере оказывается несравнимо больше, чем задач, которые можно было бы попытаться решить.

Да, символьные вычисления, с успехом выполняемые компьютерами, позволяют работать с “иррациональностями”. Но символьные вычисления происходят в других математических структурах (в других кольцах, если хотите строго) и не работают с десятичной записью действительных чисел. То есть, если записывать √2 как символ “√2”, – в том смысле, что это обозначение числа, квадрат которого равен двум, – то тут проблем нет. Но совсем другое дело – преобразование десятичной записи.

Почему это важно? Потому что алгоритм, построенный “в действительных числах” с дистрибутивностью, не будет правильно работать на реальном компьютере. Во float возникает плохое “ветвление”: например, там, где по определению действительных чисел должен быть всегда нуль, внутри float получаем нуль в одних точках, ненулевой результат – в других. Скажем, если вернуться к примеру выше, будем вычитать q из p. Ещё актуальный пример: представьте, что программа какой-нибудь нейросети обрабатывает миллиарды коэффициентов, но разработчик принял, что эта программа “работает в действительных числах” и поэтому разработчик не то что не учитывает, но даже и не рассматривает возникающие искажения.

Естественно, в хороших практических разработках это учитывается. Существенная часть практических алгоритмов в том же “машинном обучении” (Machine Learning – ML) как раз относятся к преобразованию подобных погрешностей. Корректная работа с погрешностями вообще очень важна при вычислительной обработке экспериментальных данных. Но почему-то всё равно приходится постоянно встречать утверждения, что “ML работает в действительных числах”.



Комментировать »

Один из очень мощных методов обработки радиосигналов, повышающей возможности радаров, это синтезирование апертуры антенны. Общие приципы этого метода я описывал на dxdt.ru. Вот, например, записка 2008 года. Если совсем кратко, то идея синтезирования апертуры такая: станем записывать сигналы в разных точках некоторой траектории, а потом синхронно обработаем результаты записи, учитывая координаты точек, для которых отдельные элементы были записаны. При выполнении некоторых условий – полученный результат будет близок к результату физической антенны, размер которой соответствует дистанции, пройденной при записи. То есть, пролетел отдельный приёмник с малой антенной двадцать метров – результаты синтезирования позволяют получить виртуальную двадцатиметровую антенну.

С синтезированием апертуры связан ещё один интересный аспект: для синтезирования необходимо движение, но двигаться может не только радар. Напротив, двигаться, относительно радара, – и, обычно, некоторого “фона”, подстилающей поверхности, – может наблюдаемая цель, а её движение как раз создаст “базу” для синтезирования сигнала. Это метод обратного синтезирования апертуры. Алгоритмы используются существенно более сложные, но метод неплохо подходит для распознавания и классификации типов движущихся целей. Особенно, на море, в отношении больших кораблей. Поэтому использованием обратного синтезирования особенно известен штатовский P-8 Poseidon – морской самолёт радиолокационного наблюдения, на котором применяется специальная, подвешиваемая под фюзеляж, наружная система РЛС AN/APS-154 (AAS).

Обратное синтезирование позволяет получить достаточно высокую разрешающую способность, которая, при этом, ещё и мало зависит от дальности до цели. Представьте, что радар принимает сигнал, отражённый некоторым объектом, имеющим достаточно большие линейные размеры. Пусть на объекте установлены какие-то мачты или башенки. Не так важно, что именно – главное, чтобы были геометрически обособленные элементы. Если этот объект движется относительно приёмника радара, то в разные моменты времени углы, под которыми со стороны приёмника видны эти элементы, будут меняться. Ещё лучше, если объект вращается: тогда и скорость изменения углов вырастет, и существенная разность возникнет для многих элементов. И изменение углов, и относительное движение элементов объекта, возникающие в системе координат, привязанной к приёмнику радара, означают, что во времени будут изменяться характеристики отражённого разными элементами зондирующего сигнала: будет сдвигаться фаза, изменяться частота (доплеровский сдвиг).

Синтезирование апертуры подразумевает запись сигналов на протяжении некоторого интервала времени – интервала синтезирования. Отдельные элементы реальных объёктов – это их, так сказать, упрощённое “пиксельное” представление, используемое в расчётах: в современной вычислительной радиолокации, естественно, нет никаких непрерывных областей пространства или непрерывных сигналов – всё разбивается на дискретные элементы, как по времени, так и по частоте. Соответственно, вычислитель приёмника, синтезируя записанные сигналы, использует изменения фазы и частоты, чтобы при помощи цифровой обработки собрать размытые сигналы в общий результат, с высокой разрешающей способностью.

Вообще, при обычном (прямом) синтезировании, достаточно быстро движущиеся цели дают “растянутые” вдоль некоторой траектории отметки, поскольку на интервале синтезирования успевают изменить пространственное положение (за этим эффектом стоит несколько способов селекции движущихся целей). И вот обратное синтезирование позволяет такие отметки собрать в единое изображение с дополнительными деталями. Современные радары – вычислительные, так что методы прямого и обратного синтезирования могут применяться РЛС параллельно и синхронно (см. ниже).

Понятно, что многие типы целей заведомо содержат элементы, за которые можно хорошо “зацепиться” при обработке: летательные аппараты, находящиеся в воздухе, активно маневрируют, а вертолёты ещё и быстро вращают лопастями. Корабли – раскачиваются на волнах, это эквивалентно вращению, а надстройки, мачты, антенны – всё, таким образом, даёт сильные “разностные” сдвиги: при определённых ракурсах наблюдения и движении корабля – разные отметки, соответствующие элементам конструкции, могут вообще двигаться в разных направлениях (относительно приёмника, конечно).

Проблему представляет определение параметров движения: всякое синтезирование апертуры требует некоторого опорного базиса, чтобы можно было вычислять изменения. Если это “обычное” синтезирование, то собственное положение и приёмника, и передатчика могут с высокой точностью записываться. Но когда речь про обратное синтезирование, да ещё и в отношении произвольной цели, которая свою траекторию не собирается передавать наблюдателю, возникают трудности.

Характеристики движения наблюдаемой цели можно измерить дополнительно: да, какую-то информацию даёт доплеровский сдвиг, но доплеровский эффект и так используется при синтезировании, так что возможности не так уж велики. Однако никто не запрещает определять базовые параметры движения при помощи дополнительных сигналов, а в случае достаточно продвинутых РЛС – пытаться вычислительно оптимизировать сигнал, фактически, перебирая разные варианты в поисках минимальных расхождений между базовыми точками, которые, для того же объекта, наблюдаются вспомогательными приёмниками. Можно также использовать сигнал от подстилающей поверхности в качестве опорного, вычисляя разность “от фона”. Так как наблюдаемый объект, в подавляющем большинстве случаев, и достаточно жёсткий (то есть, “хвост” не изгибается до “носа”), и несравнимо больше длины электромагнитной волны зондирующего излучения (типичная длина волны здесь – это сантиметры), то определять характеристики движения можно точно даже без высокого разрешения по углу. Почему – без? Потому что именно получение высого углового разрешения в рамках изображения одного объекта и является конечной целью обратного синтезирования апертуры: получив “картинку” с характерным силуэтом можно автоматически распознать тип наблюдаемого объекта.



Комментировать »

Утверждение, что “квантовые компьютеры” уже превосходят классические по возможностям вычислений нынче превратилось в штамп. При этом, исходное рассуждение, стоящее за идей “квантовых вычислений”, вообще-то, обратное: можно ли из наблюдаемой на практике сложности вычислительного моделирования сделать вывод о возможности разработки более быстрых, квантовых, аналоговых вычислителей? Это до сих пор не подтверждено, а из того, что конкретный способ вычислительного моделирования некоторых физических процессов работает очень медленно, по сравнению со скоростью моделируемого процесса, вовсе не следует необходимость наличия новых, превосходящих вычислительных возможностей за этими моделируемыми процессами.

Действительно, попытки точного моделирования определённых физических процессов на “пошаговых” компьютерах (классических) приводят к экспоненциальному росту вычислительной сложности. Конечно, сложность моделирования зависит от используемых алгоритмов. Тем не менее, в реальном эксперименте эти моделируемые физические процессы происходят очень быстро. Как бы, им не мешает экспоненциальная вычислительная сложность модели. Более того, в случае квантовых экспериментов, к которым относятся “квантовые компьютеры”, распределение вероятностей возможных результатов с хорошей точностью предсказывает аппарат квантовой механики, а расчёт этого предсказания – вовсе и не требует экспоненциально сложных вычислений.

Да, поскольку моделирование “квантовых вычислений”, проводимое типовыми методами классического компьютера, оказывается экспоненциально сложным, то, получается, имеющиеся возможности моделирования отстают от физического эксперимента. Но даёт ли это гарантии вычислительного превосходства? Нет.

Медленное моделирование, само по себе, это медленное моделирование, а не доказательство превосходства “квантовых вычислений”. Более того, пока что даже для случаев мнимого “превосходства” на специально подобранных задачах – появляются улучшенные методы быстрого (не “экспоненциального”) классического моделирования. Это именно что специальные алгоритмы для “некоторых типов задач”.

Но, всё же, нетрудно найти и конкретные примеры, когда возможности физического эксперимента по быстрому завершению процесса превосходят возможности классических компьютеров по моделированию исхода этого же эксперимента. У Ричарда Борчердса есть прекрасная иллюстрация (YouTube, англ.): квантовые вычисления на фарфоровом чайнике. Фарфоровый чайник, упавший на бетонный пол, разбивается существенно быстрее, чем суперкомпьютер успевает предсказать конфигурацию осколков чайника. Но только лишь из этого наблюдения – не следует обратное: что, мол, можно подключиться к сверхмощному вычислителю внутри чайника, чтобы использовать его для решения других задач.

Практические вычисления подразумевают и управление процессом, и получение полезного результата, а не только квантового шума (не путать с хайпом), чтобы с ним бороться “методами коррекции ошибок”. То есть, из практической сложности некоторого классического моделирования вовсе и не следует, что конфигурация исходного физического эксперимента гарантированно обращается – мол, можно извлечь “вычислительную мощность”.

Впрочем, трудности вычислительного моделирования тут вообще явление из параллельной плоскости. Из наличия таких трудностей не следует и то, что мощность извлечь невозможно в принципе. Тоже занимательный аспект.

Предположим, что речь идёт о симуляции вселенных, а расчёт конфигурации осколков разбитого чайника проводит некий гипервизор, реализующий симуляцию. Пока конфигурация осколков не определена, чайник не разбивается. Но этого, очевидно, обитатели симуляции не могут обнаружить – в коде не предусмотрено веток с зависанием чайника: из-за одного чайника зависает вся симуляция вокруг. Да-да, тут сразу напрашиваются эффекты склеек: что же, через некоторое время, будут видеть те обитатели, которые оказались за пределами “сектора зависшего чайника”? Вспоминаем принцип относительности Галилея и то, что в физике вокруг него. Но это уже детали, которые могут наблюдаться при помощи телескопов, а могут и нет. Главное, что если осколки чайника обсчитываются вселенским гипервизором, то, конечно, можно и нужно попробовать навязать этому гипервизору дополнительные вычисления: не то чтобы это совсем уж здравая, – в психическом, так сказать, смысле, – идея, но точно богатое теоретическое направление.

Такие вычисления могли бы выполняться быстрее, чем на суперкомпьютере в той же симуляции, поскольку суперкомпьютер обсчитывается более медленными фрагментами кода на стороне гипервизора. Почему это так? Потому что суперкомпьютер построен из отдельно моделируемых кусочков – транзисторов внутри симуляции и тому подобных элементов. Реализация каждого элемента требует ресурсов. Это как модель компьютера на “редстоун-релюшках” в Minecraft: работает, но очень медленно. А вот вычисление конфигурации осколков чайника – вселенский гипервизор реализует непосредственно, на своей аппаратуре. Могли бы это и быть “квантовые вычисления”? Да, вполне.

Вот только задача навязывания вселенскому гипервизору вычислений, во-первых, это “совсем другая история”; во-вторых, всё равно далеко не факт, что результат таких вычислений удастся простым способом спустить из гипервизора в конкретную симуляцию. Спуск может сопровождаться тем самым необратимым зашумлением, которое и обозначают “декогеренцией” и прочими забавными терминами. Мало просто выйти из “песочницы” симуляции – нужно так выйти, чтобы осталась возможность спускать результат тем процессам, которые всё ещё в песочнице. Теоретически, в такой модели, спуск – это и есть коррекция ошибок квантовых вычислителей. Которая коррекция, – внезапно! – тоже требует вычислительных ресурсов.

В общем, из сложностей конкретного вычислительного моделирования не следует наличие новых, превосходящих вычислительных возможностей “на той стороне”. То есть, если ваша модель медленная, это не означает, что моделируемый процесс именно обсчитывает сам себя быстрее – нужно доказать и то, что невозможно предложить более быстрый алгоритм с данными ограничениями, и то, что за моделируемым процессом тоже стоят вычисления, но на “другой аппаратуре” (“гипервизор”). Хорошие новости: если описанное вычислительное преимущество всё же есть, всё же оно скрывается за реализацией быстрого физического эксперимента, то классическое моделирование, действительно, всегда будет медленнее, как в случае с вселенским гипервизором выше.

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

(Это версия статьи, которую я вчера разместил на “Хабре”.)



Комментарии (3) »

Опубликовал на “Хабре” статью по теме занимательной арифметики и вычисления периода записи дробной части чисел в позиционных системах счисления. Это, фактически, развёрнутое объяснение того, почему можно на калькуляторе проверить период записи рационального числа 1/(7^11) – тут важно, что это объяснение “почему”, и на примере двоичной системы счисления (думаю, что это по теме подходит на “Хабр” хорошо), а иначе-то всю вторую часть можно сильно сократить, определив период для 1/7. Сам исходный период, для 1/(7^11), я привожу в пример в статье про шумеро-вавилонские цифры.



Комментировать »

В современном английском предложения “the bumblebee chased the ball” и “the ball chased the bumblebee” диаметрально переставляют преследующего и преследуемого только потому, что переставлены слова. Есть занятная гипотеза, почему так получилось. Если люди разговаривают на двух относительно близких языках, которые, тем не менее, имеют разные схемы словоизменения, разную морфологию, то получается, что при общении на языковой границе удобно просто отрезать от слов изменяемые элементы, оставляя только какой-то базовый вариант, фактически – корень. Ведь корни в этих языках часто одинаковые, поэтому и основное значение фразы из урезанных слов “без падежей” слушатель может понять.

“Я картошка взять. Ты деньга получь”. А вот если слова начинают изменяться по разным законам конкретного языка, да ещё и корни “перепрыгивают”, то понимать фразы становится сильно труднее: “я возьму картошку, ты получишь деньги”. Сложности добавляет и то, что при обычном говорении – речь слитная, а разделять слова слушающий может только по пограничным сочетаниям фонем (формант, если точнее): то есть, какие-то сочетания звуков не встречаются внутри слов, а только между словами – это одна из основ парсинга речи (звуковой). Но словоизменение как раз может проходить по границам слов (не всегда, не во всех языках, но довольно часто это так: “взял”, “возьмут”). Если же проговаривать лишь основную форму корня слова, да ещё и разделяя слова паузами, то эффект совсем другой.

Получается, что в результате такого пограничного перемешивания начинает “отваливаться” изменчивость отдельных слов, получается новый язык, в котором грамматическая роль задаётся относительным порядком слов и словосочетаний. Контактирующие языки обмениваются неизменяемыми частями слов, а развитое словообразование – заменяется на использование нескольких слов для уточнения значения (как “chase out the hippopotamus” – “выгони бегемота”). Естественно, один из языков будет больше подвержен влиянию другого.

И в английском сходный механизм сработал для древне-, среднеанглийского против древнескандинавских и старофранцузских диалектов. В последнем случае, со старофранцузским, потому, что схема работает и тогда, когда одна из сторон просто плохо владеет языком другой стороны. Такая вот “факторизация” языков по сумме схем словоизменения.



Комментарии (2) »

Опубликовал на “Хабре” небольшой текст про рекурсивное “центральное встраивание” (center embedding), которое доступно в английском языке, и его связь с восприятием языков и их грамматик. Речь про фразы вроде “The chap the cat the girl owned scratched screamed” – это как раз основной пример из статьи на “Хабре”. В разговорном языке, понятно, такое не встречается, но так-то у меня есть и вариант с вложенностью уровня пять (нетрудно строить по шаблону, конечно):

The ship the crocodile the chap the cat the girl owned scratched gnawed submerged resurfaced.

Годится для тестирования LLM/GPT.

The ship {
 the crocodile {
  the chap {
   the cat {
    the girl owned 
   } scratched
  } gnawed 
 } submerged 
} resurfaced.


Комментировать »

В прикладной криптографии измерение времени проявляется сразу в нескольких вариантах. Так, самое очевидное проявление – это различные сроки действия ключей. Наример, срок действия TLS-сертификата: указано, что факту соответствия открытого ключа и сетевого имени, подтверждённому при помощи цифровой подписи, нужно верить только в заданном интервале времени “не раньше – не позже” (период валидности сертификата).

Чуть менее очевидный эффект времени состоит в том, что каждой криптографической операции, связанной с использованием секретного ключа, обычно соспоставлено некоторое ожидаемое “время стойкости”: то есть, предположим, есть секретный ключ протокола Диффи-Хеллмана, он использовался один раз, соответствующий открытый параметр известен третьей стороне, примем, что эта третья сторона может вычислить секретный ключ по открытому за сто лет (тут это условное значение, но есть и куда более строгие оценки стойкости). Параметр вполне себе практический: например, уязвимые реализации ECDSA могут позволять вычислить секретный ключ по нескольким значениям подписи, но чем меньше значений – тем больше вариантов перебирать. И всякий процесс перебора тут эквивалентен указанию времени. Более того, время возникает и в момент сбора значений подписей, которые нужны для успешного подбора: предположим, что уязвимая реализация выпускает одну подпись в месяц, а собрать нужно две сотни значений.

Всё то же самое применимо и к симметричным алгоритмам: можно построить некоторое ожидание стойкости – например, 64-битный симметричный ключ для какого-то алгоритма можно считать стойким в течение недели. Опять же, условная оценка – многое как раз зависит от алгоритма, от доступных оптимизаций. 2^64 это не так мало, как может показаться: представьте, что специализированный вычислитель проверяет 1000 значений за один такт и работает на тактовой частоте 5 ГГц (зедесь и 1000, и гигагерцы – это всё время), тогда для перебора 2^64 значений потребуется полтора месяца. (А если проверка одного значения занимает много тактов, то и полный перебор сильно затянется для 2^64.)

Есть и другой аспект: утечки информации о внутреннем состоянии реализации той или иной криптосистемы, связанные с различным временем выполнения криптографических операций. Критически важные операции стараются реализовать так, чтобы они выполнялись за фиксированное время, вне зависимости от входных данных. Это требует специальных алгоритмов.

В качестве илллюстрации годится хрестоматийный случай, с которого сейчас начинаются курсы по разработке прикладных криптографических программ – утечка секретов при неверной реализации операции сравнения битовых (или байтовых) строк, когда сравнение прекращается в момент обнаружения первого расхождения. Здесь время (точнее – количество тактов), требуемое для вывода результата сравнения с секретным значением, зависит от входных данных. Если атакующая сторона может направлять произвольные данные в систему и измерять время обработки, то атакующая сторона может раскрыть секрет. Пусть секрет имеет длину 128 бит. Может показаться, что для полного перебора с гарантированным нахождением секрета нужно выполнить 2^128 запросов, то есть, потратить очень много времени. Но если реализация уязвима, имеет утчеки “по каналам времени” исполнения с разрешением в один бит, то перебрать гарантированно 128 бит побитно – можно за 128 запросов.

Но всё это – время, и в случае утечек оно играет даже две роли одновременно: утечка “по каналу времени” позволяет сократить время перебора.



Комментировать »

Нередко попадаются сообщения про “новые, самые точные часы”, и речь там не про наручный хронометр с “фазами созвездий”, да по цене Чугунного моста, а про сложные физические эксперименты с “ионными оптическими часами” и тому подобными объектами, которые обходятся даже дороже. Традиционно пишут, что эти часы – позволяют очень точно измерять время. Время, согласно действующей системе единиц СИ, измеряется в секундах. Но что такое “секунда”?

Раньше секунду определяли асторономическими методами, на основе наблюдений вращения звёзд и Солнца вокруг Земли (тут нет ошибки: именно вокруг Земли). Этот вариант определения, фактически, базировался на предположении о точности и стабильности угловых измерений. В 1960 году от астрономического определения секунды отказались, как раз по причине непредсказуемых, – но наблюдаемых, – флуктуаций земного движения. Секунду привязали к атомным процессам.

Современное определение секунды базируется на предсказаниях Стандартной модели, а именно, на том, что, согласно этой модели, частоты внутриатомных процессов стабильны и универсальны, как “во времени”, так и в пространстве. Причём, “время” – означает лишь некий порядок подсчёта количества событий: что после чего произошло, в том смысле, что есть аппаратная реализация функции, различающей события, а раз события различаются, то, зафиксировав очередной переход между отдельными событиями, можно к их количеству прибавить ещё одно. Досчитали до заранее заданного количества, до 9192631770, как сейчас, – получили одну единицу измерения: секунду. Аппаратная реализация функции – это и есть сверхточные часы. А уж атомные они или оптические, не так важно. Важно, что тут нет “времени”, в том “научпоп” смысле, который в это понятие усиленно вкладывают.

Обобщённое “время”, из новостных публикаций про сверхточные часы, – лишь популярное упрощение. Есть рекурсивный термин – “интервал времени”. Рекурсия тут начинается с применения данного термина к определению секунды. Однако в физике вообще нет “времени”. Эксперименты со соверхточными часами, будь то лазеры с ионными ловушками или более привычные атомные часы, это всё наблюдение над различными “осцилляторами”. Подсчёт некоторых периодических физических событий, например, переходов между “состояниями”. Это означает, что увеличивать точность относительно имеющегося эталона можно без наличия доступа к неким “абсолютным часам”, несмотря на то, что “абсолютное время” то и дело упоминают: если вы подсчитываете наблюдаемае изменения состояния некоторого прибора, то вот этот процесс подсчёта, основанный на упорядочивании отметок о событиях – он и есть “время”, в каком-то смысле – “абсолютное”.

Подсчитываемые события – дискретные по определению, так что нельзя увидеть, что там внутри одного такта. Грубо говоря, пусть у нас есть некий механический маятник, который спрятан в ящик и поэтому его не видно, однако в крайних положениях он замыкает электрические контакты, провода от которых выведены наружу ящика, поэтому можно считать импульсы, соответствующие крайним положениям, но нельзя достоверно определить, насколько маятник в своём движении близок к тому или иному контакту, пока этот контакт не сработал. Маятник может сколько угодно “долго” зависать в своём очередном интервале, между контактами, однако узнать о том, насколько долгим было это “долго” – не получится: на подсчёт тактов задержка никак не повлияет, поэтому она останется виртуальной.

Можно строить “рекурсивные маятники”, один за другим, соединяя их ящики таким образом, что для каждого следующего маятника выбранная теоретическая модель предсказывает, что за один такт маятника из предыдущего шага этот новый маятник – выдаёт несколько тактов, повышая разрешение. Вот только как понять, что очередной источник тактов подключился именно к основному тактовому генератору симулятора вселенных? Можно ли локально тактировать устройство с более высокой частотой, чем у основного “вселенского генератора”? Это всё сложные вопросы. К физическому измерению осцилляторов они не относятся. Так что эталон времени – это просто эталон частоты. Но этот эталон важен для процесса интерпретации действительности.

Зато к секунде, получаемой путём подсчёта переключений осцилляторов, привязано много других единиц СИ. Собственно, все, кроме моля. Так что косвенно секунда влияет на всё калибровочное оборудование, даже на оборудование для калибровки термометров. Кочнено, точность там не та, чтобы увидеть даже микросекунду, но связь всё равно есть. (В этом контексте корректировки определений занятно выглядит широко используемая сейчас при оценке изменения климата “точность” в десятые доли градуса, на интервале в полтора столетия.)

С эталонными источниками частоты/времени связана одна большая проблема: как их синхронизировать между собой? Аппаратура, на которой ведут сверхточные подсчёты эталонной частоты, очень чувствительна. Настолько чувствительна, что для конкретной локации, в которой работают такие часы, требуется учитывать гравитационный потенциал, задающий локальную практическую систему отсчёта. Что уж там говорить про колебания почвы, вызванные проезжающим мимо трамваем. Для дистанционной синхронизации таких часов сейчас используют спутниковые радиосигналы, а также и опотоволоконные линии связи. Оптоволокно в чём-то даже лучше.

Погрешность синхронизации – как раз задаёт разумный предел точности определения секунды. Скажем, если не получается синхронизировать часы с точностью лучше, условно, чем одна миллионная, то какой смысл вводить стандартное определение на уровне одной миллиардной? Ведь даже если один эталон удастся признать стабилизированным на нужной частоте, то как передать такое точное время на другие устройства? Никак. Естественно, одна миллиардная – условное число, современные эталоны точнее. Но смысл – имено такой.

Секунду в стандарте собираются переопределять. Возможно, это сделают уже в 2030 году (популярная дата). И тут прямо учитываются возможности трансляции эталонной частоты другим участникам обмена временем: если точность передачи не превышает имеющееся определение секунды, то нет причин и для переопределения. Речь тут идёт о величинах порядка 10^(-18). А помимо точных методов синхронизации по оптоволокну, разрабатывают и специальные оптические часы-эталоны, которые можно физически перевозить с места на место, сохраняя высокую точность (очевидно, с коррекцией по траектории, в том числе, гравитационной).

Новое определение секунды, в теории, может получить и полностью новый физический смысл: скажем, могут зафиксировать значение массы электрона, что позволит строго привязать секунду к прочим константам. Есть и другие варианты: например, поменяют точное значение количества импульсов, взяв за основу более высокочастотный осциллятор.

Конечно, тут наиболее интересен вариант с привязкой к фундаментальным константам, ведь именно он очередной раз подчёркивает, что, с точки зрения торетического аппарата современной физики, масса, энергия – это всё просто математические параметры: то есть, буквально, “значения переменных”. Только такая трактовка и позволяет записывать полезные “законы физики”, например, второй закон Ньютона. А времени там тем более нет.



Комментировать »

Занятная схема “навязанной” mesh-геолокации: представьте, что устройства-наблюдатели (смартфоны, скорее всего) просто периодически записывают все доступные им в радиоэфире сигналы, вычисляют для каждого короткий идентификатор (“хеш-сумму”, полученную по особому алгоритму сжатия, учитывающему физические характеристики сигнала – это важно, см. ниже), прикрепляют метку времени, накапливают эти идентификаторы, а накопленное выдают в эфир заранее согласованным способом, тоже периодически, но относительно редко, если сранивать с прослушиванием. Например, запись – десять раз в секунду, выдача – один раз в секунду. Заметьте, что тут нигде не требовалось, чтобы устройства приписывали геолокацию к записанным идентификаторам – это как раз не обязательно.

Слушать эфир можно как каким-то одним из имеющихся радиотрактов (WiFi, Bluetooth/BLE, GNSS, GSM и т.д.) или всеми сразу. Современные радиомодули очень чувствительные и избирательные. Если использовать непосредственно функции прошивки радиомодуля, то, вообще говоря, принимать можно далеко не только “логический WiFi”, но и разнообразные другие сигналы, в том числе, сигналы радаров, спутниковых передачиков (подтверждается Starlink) и т.д., и т.п. Да, приниматься могут быть гармоники побочных утечек, но для данной задачи это не важно. Если сомневаетесь, то вспомните историю появления такого направления, как RTL-SDR – там аппаратной основной вообще послужил бюджетный ТВ-тюнер. (Замечу, в скобках, что даже если в пользовательском интерфейсе смартфона указано, что соответствующие радиомодули “отключены”, это не означает, что они реально отключены – реально отключить можно было бы только в специальной архитектуре, аппаратной кнопкой, но таким практически никто не пользуется, да и кнопка не даёт полной гарантии.)

Устройства-наблюдатели по данной теме больше ничего не делают, поэтому их активность снаружи выглядит вполне себе обычно (это, собственно, просто логика протоколов класса LTE). Однако собранные сведения из эфира принимает какое-нибудь внешнее устройство-монитор, специально предназначенное для этого. Принимает тогда, когда удалось что-то принять. Монитором может быть и другой, скомпрометированный, смартфон, и штатно подготовленный приёмник “базовой станции” с нужной прошивкой – не так важно, но возможности, конечно, различаются. Монитор знает собственное местоположение, может знать направление, с которого получен очередной блок данных (это больше относится к “базовым станциям”). Полученные от наблюдателей данные монитор передаёт на удалённый центральный сервер. Этот сервер агрегирует данные от многих мониторов.

Теперь на сервере, зная возможности приёма и принципы распространения радиоволн, можно вычислять где какие метки в эфире были видны – то есть, выполнять геолокацию идентификаторов. Устройства-наблюдатели ведь будут видеть и друг друга, и базовые станции сетей мобильной связи. Сопоставляя данные от разных мониторов, географические координаты которых известны точно, получится определить, где находились и устройства-наблюдатели, и источники радиосигналов, которые эти наблюдатели обнаружили в эфире. Метод основан на переборе конфигураций, в которых многие наблюдатели могли принимать одни и те же сигналы, чтобы в итоге получилась такая же картина, как та, что поступила с нескольких мониторов.

Да, такая задача сопоставления меток времени и возможностей приёма – вычислительно сложная, но и компьютеры сейчас мощные. Алгоритмы вычисления идентификаторов сигналов (специализированные “хеш-функции”, упомянутые в самом начале) должны быть так устроены, чтобы близкие по физическим характеристикам радиосигналы получали близкие по значению идентификаторы. Это и позволит найти следы одного и того же источника в массивах идентификаторов, полученных от разных мониторов. Результат не самый точный, но, во-первых, чем больше источников данных, тем выше точность; во-вторых, других вариантов сбора данных может и не быть, однако если они есть, то накопленный по описанной схеме массив идентификаторов позволяет эти другие данные подтвердить или опровергнуть с очень высокой степенью достоверности.

Теперь представьте, что в схеме участвует спутниковая группировка на низкой орбите, которая может принимать сигналы смартфонов, находящихся на земле. Конечно, не только принимать, но и выдавать синхроимпульсы, которые уже примут устройства-наблюдатели, чтобы вернуть через мониторы обратно, на обработку. Тут спектр возможностей становится удивительно широким.



Комментировать »

(Это существенно дополненная версия статьи, которую я недавно публиковал на “Хабре”. Дальше используются клинописные знаки из Unicode. Если в тексте на вашем устройстве клинопись не отображается, то это из-за отсутствия шрифтов; добавьте шрифты с клинописным блоком, cuneiform; например – Noto.)

На древних глиняных табличках из Месопотамии встречаются математические тексты с достаточно сложными вычислениями. Кроме прочего, для записи чисел использовалась шестидесятеричная система, которая имеет существенное «компьютерное» преимущество перед современной десятичной. Древняя шумеро-вавилонская система счисления это позиционная система по основанию шестьдесят: каждой позиции соответствует количество единиц, умноженное на степень 60, значения позиций – суммируются. Обычный способ. Шумеро-вавилонская клинописная цифра 42 выглядит так: 𒐏𒐖. И это именно цифра, которой может соответствовать и число 42, и 2520, и 151200 и так далее (всё в десятичной системе), по степеням 60. То есть, 42, как число, – это 42 единицы, для 60^0 (в нулевой степени). А десятичное 151200 – это 42 * 60^2. И так далее. Доли представляются по обратным степеням основания, например: 42 * 1/60, 42 * 1/(60^2) == 42 * 1/(3600).

Поскольку основание 60, то нужно 59 цифр. Откуда и цифра 42 (конечно, 42 тут – это условное обозначение, поэтому к нему даже можно не приписывать указание на десятичную систему).

В клинописной записи отдельных цифр вертикальные “палки” обозначают единицы, если их количество не превышает 9, а “галки” – обозначают десятки, что, впрочем, не делает систему десятеричной. Так, 𒐏𒐖 – это четыре “галки” и две “палки”, соответственно: 10 * 4 + 2 * 1. (Кстати, с какой стороны тут правильно писать количество знаков, а с какой – вес? Это ещё один пример того, что порядок записи важен, и логическая часть практически всегда некоммутативная.)

Вообще, древнейшние шумерские системы счисления использовали для записи цифр круги и “полуовалы” – примеры есть в отдельной записке. “Галки” и “палки” появились позднее, когда система стала логически стройнее.

Sumerian Tablet
(Очень древняя табличка. Credit: Metropolitan Museum of Art.)

На иллюстрации выше – пример таблички (3100–2900 B.C.) со знаками, соответствующими кругам и “полуовалам” по способу построения. Видимо, это учёт кувшинов и мехов – нарисованы рядом. Точная интерпретация значений цифр на самых древних табличках трудна, так как система ещё не имела строгой типизации: в самых древних шумерских вариантах интерпретация цифр зависела ещё и от того, что именно подсчитывается. Использовался ли знак для обозначения мер зерновых, для записи количества кувшинов масла или площади земельного надела – числовое значение могло быть разным. Это в точности современный Javascript, неявно преобразующий строку в числовой тип.

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

Протоклинописных кругов и “полуовалов” всё ещё нет в стандартном Unicode. Но есть предложение по добавлению нужных символов.

Cuneiform in Unicode

На этой иллюстрации – фрагмент таблицы начертаний древних шумерских цифр, которые предлагается добавить в соответствующий блок Unicode. Из состава таблицы нетрудно сделать вывод, что композиций протоклинописных знаков, встречающихся на табличках, гораздо больше, чем простой круг и не менее простой “полуовал”. Ещё больше вариантов образуется в результате интерпретации исходной записи. Скорее всего, недостаток детализации и отсутствие арифметической строгости беспокоил и древних пользователей. Поэтому способ записи модифицировали, заменив круглые цифры на системы “галок” и “палок”. Получилась, так сказать, более привычная шестидесятеричная клинописная система. Способ записи стал стройнее, а шумеро-вавлионские цифры – стали более доступными для современного взгляда. Эта система более привычна и в смысле Unicode.

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

Выбор числа 60 в качестве основания имеет арифметическое обоснование. У шестидесятеричной системы большое преимущество, если сравнивать, например, с десятеричной, а тем более – с двоичной, восьмеричной и шестнадцатеричной. Всё потому, что число шестьдесят – “очень непростое”: 60 = (2 * 2) * 3 * 5. В результате, арифметика записи по основанию шестьдесят оказывается удобной для отображения долей целых – можно самые ходовые доли записать точно: 1/2, 1/3, 1/4, 1/5, 1/6, 1/10, 1/12, 1/15, 1/20, 1/30, ведь знаменатели здесь являются делителями 60. “Точная запись” же означает, что для обозначения не придётся использовать бесконечную запись, как 0.333(3) для 1/3 в десятеричном случае. О точности более подробно рассказано ниже. Прежде чем перейти к дробям, нужно получше разобраться с шумерскими клинописными цифрами.

Итак, цифрами служили комбинации клинописных знаков. Мы уже назвали их “галки” и “палки”, что соответствует их начертанию и в Unicode, и на табличках. 𒌋 – это “галка”, которая соответствует десяти единицам; 𒐕 – это “палка”, которая соответствует единице. Единицы в количестве менее десяти записывались в виде плотного набора “палок”: 𒐛 – это семь. 𒌋𒌋𒐗 – это цифра, которой, если считать цифры по порядку, соответствует число 23, записанное десятично. “23”, как цифра, – не обязательно обозначает число 23. “Галки” повторялись кратно десяти единицам: 𒌋𒌋 – двадцать. Группироваться наборы “галок” и “палок” могли произвольно, что может затруднить разбор. Мы будем использовать запись, когда единицы переходят на вторую “строку”, если их больше четырёх, а десятки – группируются вертикально: 𒐏𒐝 – это цифра 49. Можно считать, что число 49 это порядковый номер сорок девятой цифры.

Возьмём снова цифру 23: 𒌋𒌋𒐗. В зависимости от позиции и от контекста эта цифра может обозначать единицы, то есть нулевую степень основания (60^0 == 1), или единицы при 60^1, или единицы при 60^2 = 3600. Соответственно, 𒌋𒌋𒐗 (“23”) в позиции единиц – это число 23 в десятичной системе. 𒌋𒌋𒐗 в позиции 60^1 это 23 * 60 = 1380 (в десятичной). А для второй степени: 23 * 60^2 = 82800 (десятичная).

Tablets and 42
(Цифра 42)

На коллаже выше – клинописная цифра “42” шумеро-вавилонской системы счисления. Вверху – современная запись (Unicode + шрифт, поддерживающий клинопись). Ниже – два варианта записи той же цифры на табличках: P493016 (середина коллажа) и P257557 (внизу). Обе таблички датируются 1900-1600 B.C. При этом на нижней табличке использован способ группировки десятков в цифрах, который отличается и от варианта на табличке в центре, и от варианта Unicode. Но, думаю, теперь нетрудно догадаться, где там что.

Позиции в записи чисел разделялись пробелами, что не всегда однозначно, из-за того, что нуля не было. 𒐖 𒌋𒐗 это, например, 2*60^1 + 13 = 133. Почему “например”? Потому что это система с плавающей точкой. 𒐖 𒌋𒐗 с тем же успехом можно интерпретировать как 2 + 13/60. Здесь 13/60 = 13*(1/60) – это интерпретация 𒌋𒐗 как 13 “обратных” долей, по степени 60^1. То есть, плавающая точка переплывает вправо на одно знакоместо. Такой произвольный сдвиг точки очень удобен с точки зрения вычислений по таблицам значений, мы в этом убедимся на примерах далее. И если данная особенность сильно помогает при практических вычислениях, то она же мешает при считывании результата спустя всего лишь три-четыре тысячи лет.

Выходит, что с шумерскими цифрами всё достаточно просто: это различать клинья на реальных табличках трудно, но не схему записи.

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

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

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

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

В древние времена, когда компьютеры были редкими и очень большими, данные в память вводили вручную, нажимая кнопки-биты и перещёлкивая тумблер записи. Если ваш компьютер работал на байтовых ячейках, – то есть, в один октет, восемь бит, – то опытный оператор мог каждую шестнадцатеричную цифру заданного значения моментально “выкинуть” на четырёх пальцах руки: каждый палец – один бит. Если бит установлен, то и палец выставляется вперёд, для нажатия на кнопку системы набора. 0xF – четыре пальца. 0x8 – указательный или мезинец, в зависимости от того, “тупоконечные” у вас пальцы или “остроконечные”. Не в смысле формы, а в смысле того, с какой стороны старший бит байта в представлении вашего компьютера. И так далее – прочие варианты “распальцовок” читателю предлагается отработать самостоятельно. Нынче навык сей доступен разве что редкому динозавру-технарю, да и не так полезен, однако верная распальцовка всё ещё может быть эффективно использована в беседе с молодыми DevOps, для пущего их убеждения. Заметьте, что две руки – это байт, а большим пальцем можно ловко перещёлкнуть тумблер записи, перейдя к следующему адресу. Хотя, тумблеров на компьютерах больше нет.

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

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

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

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

Например, 1/5 == 0x0.33(3) – всё в шестнадцатеричной системе, а тройка здесь – в периоде (обозначается скобками). “В периоде” – это значит, что развернутая запись никогда не окончится. Однако в десятичной записи 1/5 == 0.2 – и точка. “Периода” нет, запись терминируется тут же. И это одно и то же рациональное число – одна пятая.

Да, формально, и 0x0.33(3), благодаря возможности обозначить “периодические цифры”, это точная конечная запись для 1/5. Да, к 0.2, если уж быть максимально строгим, должен быть приписан бесконечный хвост нулей – 0.2(0), но его принято не указывать (да вообще мало кто помнит, что он там есть, но его не видно; как и про второе представление с бесконечно повторяющимися девятками, для десятичной системы). Это всё так по определению, а требуется по тем же причинам, по которым в десятеричной (десятичной) системе 0.9(9) == 1.

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

Заметьте, что 0x0.3 * 0x5 == 0x0.F. Аналогично тому, как 0.3 * 3 == 0.9. Но почему в десятичной системе 1/5 = 0.2? Потому что 10 == 2*5. Соответственно, все числа, представимые в виде 2^n * 5^m, будут регулярными в десятичной системе: “обратные” к ним можно записать в виде конечной дроби. Шестнадцатеричная же система имеет основание 2^4, а число 5 нельзя представить в виде 2^n, отсюда и дробная часть в периоде.

По тем же причинам 1/7 = 0x0.249(249). Шестнадцатеричная система. Три цифры – период.

А вот для 1/(7^11) период шестнадцатеричной записи после запятой составит 847425747 цифр (цифры записи будут шестнадцатеричные, но их количество – записано в десятичной системе, проверьте на калькуляторе). Так что проблема точной записи, даже если позволяется вводить дополнительную структуру и указывать период в скобках, – остаётся. Кстати, поскольку в разложении 10 есть 2, то найти столь же иллюстративный обратный пример – число, которое “хорошо” представляется в шестнадцатеричной системе, но “плохо” в десятичной, – не выйдет.

Будем обозначать клинописные цифры десятичной записью соответствующего числа, разделять цифры будем запятой “,”, а точку-разделитель целой и дробной части (мантиссы) – обозначим точкой с запятой (“;”). Это общепринятый сейчас способ. Тогда 1/7 в шестидесятеричной шумеро-вавилонской системе это 0; 8,34,17(,8,34,17) или клинописью:
𒐜 𒌍𒐘 𒌋𒐛 𒐜 𒌍𒐘 𒌋𒐛… (тут цифры повторяются с периодом три).

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

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

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

Разделим 10,30 на 1,15. Это уже шумерские цифры (см. нотацию выше). То есть, 10,30 == 630 в десятичной, а 1,15 == 75 в десятичной. Найдём обратный к 1,15 – это 48, потому что 1,15 * 48 == 1, а именно – 3600 в десятичной записи; выше мы разобрались, что в шумерской системе нет строгой разбивки по позициям, поэтому единица для 3600 соответствует позиции с весом 60^2. Найдём результат умножения 48 на 10,30. Это 8,24 (нуля у нас нет – не забывайте). Как получилось 8,24? Скорее всего, для шумерского инженера-информатика это табличный результат – то есть, он должен быть уже записан на глиняной табличке умножения. Если же не записан, то инженер-информатик быстро вычислит его в уме, поскольку хорошо владет шестидесятеричной системой.

Посудите сами: 30 – это половина от “единицы”, то есть, половина от основания системы, от 60. Соответственно, умножать на 30 просто – работает так же, как умножение на 5 в десятеричной системе: умножаем на 1 и берём половину. Но 1, конечно, это 60 в десятеричной. То есть, нужно взять половину от значения цифры 48 – записываем цифру 24, всё в соответствии с таблицей умножения. И не забываем, что позиция плавающей точки только что сдвинулась вправо, ведь при умножении 48 на единицу, мы взяли эту единицу в позиции с весом 60, но исходная цифра 48 – это количество единиц в позиции с весом тоже единица (60^0). Естественно, если корректно отслеживать положение плавающей точки, то метод работает для любой позиции цифры 48. Так что – обычное быстрое умножение, сдвигами.

Теперь цифра 10 из 10,30. 10 – это одна шестая от основания системы, тоже удобно. Умножаем на единицу и берём одну шестую. Одна шестая от 48 – это 8. Поэтому и цифра будет 8, но она должна стоять в правильной позиции – то есть, на одну позицию левее. Перенос плавающей точки здесь соответствует “переносу единиц” в привычном умножении столбиком в десятеричной системе, но из-за большого количества делителей основания системы 60, схема оказывается более эффективной.

Итак, получили 8,24, в шумерских цифрах. Обратите внимание, что сейчас, после умножения “на обратный”, 8 находится в позиции с весом 60^2, а 24 – в позиции с весом 60. Поставим “плавующую точку” на место, сдвинув, как положено, на две позиции левее, и получим верный результат: 8; 24.

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

𒌋 𒌍 / 𒐕 𒌋𒐙 (здесь “слеш” – знак деления),

обратный: 𒐏𒐜, умножаем по таблице: 𒐏𒐜 * 𒌋 𒌍.

Результат: 𒐜 𒌋𒌋𒐘 – и через те самые несколько тысяч лет придётся догадываться, где же здесь стоит плавающая точка.

Всё это так хорошо работает потому, что 48 == 2^3 * 6, 10 == 2 * 5, 30 == 5 * 6 и т.д. Это всё регулярные числа, которые записываются точно в шеcтидесятеричной системе. Чуть выше мы нашли, что 1/7 в шумеро-вавилонской системе нельзя представить точно, потому что запись будет бесконечной: 𒐜 𒌍𒐘 𒌋𒐛 𒐜 𒌍𒐘 𒌋𒐛… Так происходит потому, что 7 – взаимно простое с основанием 60.

Знали ли об этом древние шумеры и вавилоняне? Скорее всего, да, знали, но трактовали это явление иначе, чем сейчас: для древнего шумерского инженера-информатика рациональное число 1/7 было бы не “рациональным”, а “невозможным”, в том смысле, что такую долю невозможно записать точно в шестидесятеричной системе, поэтому в точных таблицах нет обратного значения. Непонятно, как считать, поэтому 1/7 не должна встречаться на практике. Конечно, если 1/7 всё же встретилась, то инженеру-информатику пришлось бы воспользоваться таблицами “приближённых” значений, подобрав подходящий интервал. Такие таблицы тоже имелись, но их наверняка старались избегать, ведь иначе шестидесятеричная система оказывается избыточной.



Комментировать »

Повышение уровня абстракции – полезный и важный элемент процесса обдумывания, так как позволяет задействовать механизм “разрешения противоречий”. Если такой механизм есть, конечно.

Возьмём пару цитат и ещё одну, не менее замечательную:

“Нас невозможно сбить с пути, нам всё равно, куда идти”
М. М. Жванецкий(?), (есть вариант “никому не сбить”, не важно).

“У самурая нет цели – только Путь”
“Хагакурэ”, Ямамото Цунэтомо. (Иногда напоминаю коллегам эту важную максиму.)

Это почти об одном и том же. В первой цитате – всё равно, куда идти, но идти необходимо, иначе исчезает содержательная часть. Именно ход создаёт путь, который, по определению, тут не может вести к конкретной цели. Цели нет. Только Путь. Как и у самурая из второй цитаты. Почти.

“Всё равно куда” перекликается с одной из самых знаменитых цитат из “Алисы в Стране чудес”:

”
– Скажите, пожалуйста, куда мне отсюда идти?
– А куда ты хочешь попасть? – ответил Кот.
– Мне все равно… – сказала Алиса.
– Тогда все равно, куда и идти, – заметил Кот.
– …только бы попасть куда-нибудь, – пояснила Алиса.
– Куда-нибудь ты обязательно попадешь, – сказал Кот. – Нужно только достаточно долго идти.
“

Л. Кэрролл.

Эта цитата содержит машинерю, позволяющую детально разобрать две предыдущих цитаты. Всё равно, куда идти. Но если идти достаточно долго, то куда-нибудь попадёшь. Долгий ход, как сейчас говорят, “определяет”. Если недостаточно долго идти, то не получится дойти даже куда-нибудь (настолько размытое пространство). Как понять, что идёшь уже достаточно долго? Нужна точка отсчёта, иначе всякий раз может оказаться, что ход недостаточно долгий и никуда не приводит. Где предельный переход? Возможен ли он? У самурая нет этих проблем, из-за глубинных свойств его пути.

Занятно, что, согласно “Алисе в Стране чудес”, даже когда путь отделяется от цели, он обязательно приводит куда-нибудь. Это здесь чисто категорийное свойство пути – приводить куда-то. Стрелка.

К сожалению, такое определение недостаточно абстрактно: выходит, что если начать просто “идти” и “идти”, то это ещё не путь. В “невозможно сбить с пути”, не только путь появляется раньше цели, но и сказано, что куда-то мы должны идти. Да, всё равно – куда, но ведь – куда-то! Тем не менее, попытка отделить свойство, создающее путь, от цели, через “невозможность сбить с пути”, это абстракция достаточно высокого уровня, чтобы начать строить теорию категорий. Удивительно.

Тут-то и можно заметить преимущество положения самурая из самурайской цитаты, по сравнению с ситуацией “всё равно куда”. Во “всё равно куда” – цель неявно проступает, если попытаться задуматься и начать искать способ разрешения противоречий: как определить, что всё равно, куда? Ведь “куда” подразумевает некоторое направление пути, почти что цель. Для “куда” нужно ввести дополнительные понятия, чтобы отличать одно “куда” от “другого”. А про самурая нельзя сказать, что ему всё равно, куда идти. У самурая отсутствие цели постулируется, так что “куда” – просто не возникает. Все “куда” поднимаются для самурая в Путь (см. иллюстрацию).

Дзен самурая – дзен более высокого уровня, на фоне которого “всё равно куда” выглядит некоторым мельтешением: суетятся, бегают куда-то, всё равно, куда – лишь бы бегать. Самурай не суетится. У самурая нет цели. Только путь.



Комментарии (1) »