[Прим. пер.: на Хабре уже был перевод этой статьи, но незавершённый примерно на четверть.]
Неправда.
Калькулятор должен показывать результат введённого математического выражения. А это намно-о-ого сложнее, чем кажется.
В этом посте я расскажу величайшую историю о разработке приложения-калькулятора.

На изображении выше показан калькулятор из iOS.
Заметили что-нибудь?
Он посчитал неправильно.
(10100) + 1 − (10100) равно 1, а не 0.
Android считает правильно. А причина, по которой он это делает, абсолютно безумна.

Google нанял Ханса-Юргена Бёма, знаменитого созданием «сборщика мусора Бёма» (Boehm garbage collector). Компании нужен был элитный кодер, способный решить проблемы сборки мусора и параллельного программирования. Он возглавил проект по разработке семантики разделяемых переменных C++. Но потом Google дал ему задачу, которую невозможно решить: создание приложения-калькулятора.

Наверно, даже для него это было сложно.
Задача калькулятора — давать правильные ответы. Числа с плавающей запятой неточны — они не могут представить 0,3 или 10100. То есть создание калькулятора на основе чисел с плавающей запятой похоже на строительство дома на песке.

Наверно, это стоит объяснить подробнее: чтобы давать правильные ответы математических выражений, калькулятор должен обрабатывать числа.
Но почти никакие числа невозможно выразить в стандарте чисел с плавающей запятой IEEE.
Для получения точных ответов при даже самых простых операциях с такими числами требуется тщательно всё продумывать.
Некоторых проблем можно избежать, если пользоваться арифметикой с произвольной точностью (bignum-арифметикой).
Большинство числовых типов всегда имеют длину 2 или 4 байта. Но с bignum всё не так. Это безграничные целые числа, которые при необходимости разрастаются в памяти.
Это решает проблему с примером (10100) + 1 - (10100). Но bignum — это целые числа. А как же насчёт дробей?

Проблема дробей легко решается: достаточно использовать bignum для числителя и знаменателя. Реализация арифметических операций с такими типами тривиальна и всегда даёт точные ответы.
На этом многие бы начали праздновать победу. Но Бёма это не удовлетворило.

Математика — это далеко не только одни дроби. Как насчёт π или √2? Калькулятор, построенный на основе дробей с произвольной точностью, не сможет вычислить длину окружности, потому что π нельзя выразить в виде дроби.
Если калькулятор не способен справиться с математикой девятого класса школы, то кому он нужен?

Приблизиться к решению Бёму позволила алгебраическая арифметика.
Забудьте о представлении чисел в виде числителей и знаменателей.
Можно представить их в виде степенного уравнения.
Для √2 это будет x² - 2 = 0. (Плюс необходимо хранить информацию, что нам нужен только положительный корень.)

Теперь математические операции реализовать будет сложнее:
Для сложения нужно создать новый многочлен, корень которого является суммой слагаемых
Для умножения нужно использовать композицию многочленов и результанты
И знаете что? Бёму всё равно этого было недостаточно. Это сработает только с алгебраическими числами, но не с π. Поэтому Бёму не оставалось ничего другого, кроме как ещё глубже закапываться в проблему.
Мы начали с целых чисел (bignum), перешли к рациональным числам, затем к алгебраическим. Что дальше?
Конструктивные вещественные числа.

Так Бём начал исследовать «рекурсивную вещественную арифметику» (recursive real arithmetic, RRA). Для выражения и указанной точности RRA позволяет получить ответ как минимум с этой точностью.
Посмотрите на обложку этого старого учебника. Видите, что линейки становятся всё меньше и меньше?

Конструктивные вещественные числа — это такие числа, которые можно вычислять со всё большей и большей точностью.
Мы никогда не сможем перечислить все цифры после запятой в π. Но если я спрошу рациональное число на расстоянии не больше 0,01 от π, то вы назовёте 3,14.
π находится в пределах 0,01 от 3,14, так что это правильный ответ.

Допустим теперь, что я спрошу число на расстоянии 0,01 от 2π.
Вы знаете, как получать цифры π после запятой (3,14159...).
Можно умножить их на 2. Но сколько разрядов нужно взять, чтобы ответ точно был в окрестности 0,01 от 2π?
Умножение числа на 2 удваивает погрешность. Я спросил число в окрестности 0,01 от 2π, поэтому нам нужна аппроксимация π в окрестностях 0,005.
Допустим, вы получили 3,141, что и в самом деле находится на расстоянии меньше 0,005 от π. Умножим его на 2 и готово!

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

Благодаря этому RRA легко использовать. Вы говорите, насколько точным должен быть ответ, а она рекурсивно определяет необходимую точность во всех промежуточных вычислениях.
Она без проблем может работать с выражениями, где есть π или √2. А калькулятору без этого не обойтись.
Вы, наверно, думаете, что Бём на этом остановился?
В качестве «точности вывода» он указал количество разрядов калькулятора, ведь так?
Тогда все отображаемые на калькуляторе разряды будут правильными, а значит, теперь он всегда будет показывать правильный ответ! Ведь так?
Не будем торопиться. Когда пользователь вводит «1-1», то ответом должен быть 0, поэтому мы хотим показать «0».
Однако RRA только сообщит нам, что «1-1 находится в пределах погрешности округления 0,0000000000000»
Если показывать на экране 0,0000000000000, когда ответ равен 0, то это будет ужасно с точки зрения UX.

Бём снова вернулся к анализу. Наверно, он уже был сильно озадачен. По сравнению с этой проблемой его «эффективно использующая пространство консервативная сборка мусора» казалась детской забавой.
В одиночку он бы не справился, поэтому призвал на помощь своих коллег, например Роберта Картрайта и Вернона Ли

Мы можем проверить два RRA-числа на неравенство. Можно вычислять их со всё большей и большей точностью, пока мы не увидим, что они различаются.
Но если числа равны, то мы бесконечно будем вычислять их со всё большей точностью. Этот процесс не имеет завершения, это алгоритмически неразрешимая задача.
Вспомним, что если калькулятор покажет 0 как ответ выражения e-10000, то это будет неверно. Он должен показать 0,00000... и позволить вам проскроллить все нули, чтобы найти, где появляются другие значения. Но он ДОЛЖЕН показывать 0 при вводе sin(π), потому что sin(π) точно равен 0. RRA никак не позволяет нам определить, что sin(π) точно равен 0. Или можно просто не давать ответ, как это делает калькулятор iOS:

То есть задачу отображения точного ответа невозможно решить при помощи конструктивных вещественных чисел. Но потом Бёма и его коллег осенило: им не нужно работать с конструктивными вещественными числами. Достаточно работать только с числами, которые можно выразить при помощи имеющихся в калькуляторе операций
А именно:
Четырьмя базовыми арифметическими операциями и квадратными корнями.
Тригонометрическими функциями sin, cos и tan, а также обратными им функциями.
Степенными функциями и (натуральными) логарифмами
Это гораздо меньшее множество чисел, чем все конструктивные вещественные. И оказалось, что другие люди уже исследовали именно эту задачу. Их звали Дэн Ричардсон и Джон Фитч. Они решили её в 1994 году.

Их решение было абсолютно корректным, за исключением случаев, когда одно из чисел оказывается контрпримером гипотезы Шануэля.
Но на самом деле такого никогда не случится.
Гипотеза Шануэля — одна из важнейших в теории чисел, и пока никто не нашёл для неё контрпримера.
Похоже на идеальное решение. Но есть лишь одна проблема: оно слишком медленное.
1 не равно 1 - e(-e^1000). Но чтобы это определил алгоритм Ричардсона и Фитча, потребуется больше этапов, чем атомов во Вселенной. Нужно было придумать что-то более быстрое. Изначально Бём с коллегами ставили задачу определения равенства двух конструктивных вещественных чисел. А её решить невозможно. Они упростили её и приблизились к решению, ограничив способы конструирования чисел. Это сделало задачу решаемой, но медленно.
Можно ли ещё раз упростить её?
Они поняли, что нет ничего особо страшного в том, чтобы показывать «0,000000...» в случае, когда ответ равен 0, хоть это и неидеальный UX. Нельзя лишь показывать «0» в случае, когда ответ 0,0000001.
Может быть, есть какой-то более быстрый консервативный алгоритм?
И они придумали нечто поистине великолепное.
RRA даёт нам всю мощь конструктивных вещественных чисел, но имеет один недостаток: с её помощью невозможно получить точные ответы. Рациональная арифметика даёт точные ответы, но не может выразить π. Можно ли объединить их сильные стороны?
Разработчики осознали, что если пользователь просто вводит 6 * 9 или 8 / 3, то полная мощь RRA не требуется, достаточно рациональной арифметики. RRA нужна только в случаях, когда рациональных чисел недостаточно. Можно использовать её, когда в дело вступают числа наподобие π или √2, а в остальных случаях применять рациональные числа
Рациональные числа точны, но в них нельзя выразить π.
RRA-числа могут описывать числа наподобие π, но не могут быть точными.
Разработчики придумали такое решение: представлять каждое число как рациональное, умноженное на RRA-число. Но этого недостаточно. Как только в дело вступают RRA-числа, результат обязательно становится неточным.

Но даже в случае иррациональных чисел RRA иногда может быть излишней.
RRA представляет π в виде функции, способной возвращать рациональные числа, с произвольной точностью близкие к π. (Точно так же, как все RRA-числа представляются в виде функций)
Можно сказать: «Мне нужно число π с точностью 0,001», и RRA ответит: «это 3,141»

Иногда нам нужна RRA. Но на этот случай можно просто иметь особое представление π, которое мы будем особым образом использовать вместо её функции RRA. Мы называем это символьным представлением, поскольку это похоже на написание символа π вместо бесконечной последовательности чисел

Ага, дело пошло. А теперь давайте сделаем так не только для π. Очевидно, что нам нужно символьное представление вещественного числа 1. Но многие используемые нами иррациональные числа — это результат применения операции к рациональному аргументу. Для них можно тоже создать символьные представления.
Разработчики решили хранить символьные представления для √arg, eᵃʳᵍ, ln(arg), log₁₀(arg), sin(πarg), tan(πarg) и других функций (где arg — это какое-то рациональное число).
Итак, окончательное представление чисел выглядит так: рациональное, умноженное на вещественное, где вещественное — это или RRA-вещественное, или символьное вещественное.

Необходимо помнить, что фундаментальная проблема заключается в невозможности проверки RRA-чисел на равенство. Как только мы используем такое число, всё вычисление становится неточным, но иногда они необходимы. То есть Бёму и его коллегам достаточно было максимально избегать использования RRA-вещественных чисел!
Например, в (1 × π) + (3 × π) у нас, к счастью, есть символьные представления вещественных чисел. В обоих случаях это π.
Так как вещественные части одинаковы, мы можем выполнить суммирование, сложив рациональные части.
Если бы выражение имело вид (1 × π) + (3 × √2), то для вычислений мы бы использовали RRA.
Благодаря этому представлению разработчики добились баланса: все отображаемые на экране разряды всегда правильны и почти никогда не отображается больше разрядов, чем это необходимо.
«Система компьютерной алгебры» решила бы схожую задачу, но была бы гораздо медленнее и сложнее. Такая система настолько сложна, что её поддержкой на уровне продакшена способны заниматься очень немногие. А Бём и его коллеги придумали на 100% корректную систему, в 99% случаев обеспечивающую идеальный UX и ценой всего 1% сложности реализации.
Вот что называется настоящей разработкой ПО! Вам стоит прочитать статью Ханса-Юргена Бёма Towards an API for the Real Numbers.
Надеюсь, теперь вы больше будете ценить калькулятор в Android!
Комментарии (113)
Zenitchik
18.02.2025 08:53В реальной жизни такие большие числа не бывают такими точными. Поэтому 0 - правильный ответ.
А я, когда число не может быть представлено в float64 как целое, принудительно меняю формат вывода на экспоненциальный.
unreal_undead2
18.02.2025 08:53Видимо, для гугла было принципиально точно обрабатывать числа порядка гугла )
goldexer
18.02.2025 08:53А потом мы видим множество споров под простым 6÷2(1+2) и два калькулятора (один из которых инженерный, а второй студенты писали), показывающих разные ответы. Никто не вдается в подробности, почему именно знак перед скобкой опущен. Просто что-то такое смутно помнят со школы, мол, раз знака нет, значит умножение, а раз умножение, значит по порядку и решаем. Арифметика или алгебраика - не всё ли равно им? Представляете, даже такой простой пример, показывает, что перед тем как позволить пользоваться калькулятором, людям надо вручить ещё и инструкцию к нему. Да-да, из того же разряда, что и «сушить кошку в микроволновке запрещено». Так что да, написать грамотный калькулятор - весьма непростая задача... Благодарю за статью и пойду открою окно, а то надушнил вам тут)))
stanislavskijvlad
18.02.2025 08:536÷2(1+2)
Тут всё (не)просто. Во-первых, есть раннее или строгое(сильное) связываение. 2a — это два А, а не просто А два раза. Потому что 2а/2а = 1 , а не а². Понимаете ? Во-вторых, в дробях всё, что числитель — это одно, а всё, что знаменатель — это другое. Дроби крутые сами по себе, а с рядами Тейлора/Фурье/Маклорена так просто мега имба. И можно было бы определить знак / как последовательное деление, а ÷ (обелюс) сделать знаком дроби в линейной записи. Точки обозначали бы числитель и знаменатель. Тогда 6÷2(1+2) становится (6)÷(2(1+2)). Ну и третье. Обратная польская нотация решает и даёт одназначность толкования. Писали же про стековый калькулятор. Автор ещё уточнил, что особенно любит их.
whitedog36
18.02.2025 08:53Что за бред...
2a – это просто другая запись 2×a. И из-за другой записи приоритет не меняется.
И не надо выдумывать, что было бы по-другому, то было бы круто.
VBDUnit
18.02.2025 08:53Есть две разных нотации, ЕИНИП. В одной 2а трактуется как простое 2×a, в другой эта операция трактуется как умножение с повышенным приоритетом. И, в зависимости от того, как человека выучили, он будет трактовать это так или иначе. Поэтому люди и спорили.
khajiit
18.02.2025 08:53Чтобы не было бреда, надо, во-первых, даже денормализованные дроби записывать правильно. Во-вторых: явно указывать приоритеты скобками.
А если намеренно пишешь двусмысленную фигню и рассчитываешь, что тебя телепатически поймут — то это к другому доктору.
NVVI
18.02.2025 08:53Для некоторых математических выражений (типа
) в принципе не существует однозначной интерпретации. В Википедии есть несколько абзацев на эту тему. Что-то типа undefined behaviour в языках программирования.
Aleshonne
18.02.2025 08:53Да просто последовательность символов «6÷2(1+2)» не является математическим выражением, хотя и состоит из знаков, которые обычно используют для написания таковых. Это аналогично тому, что не любая комбинация операторов языка программирования является компьютерной программой.
karavan_750
18.02.2025 08:536÷2(1+2)
На эту тему Борис Трушин достаточно емко сказал.
Недословно. Математическим выражением может являться только то выражение, которое понимается однозначно. Если выражение допускает вольности интерпретации, то оно не математическое.
VBDUnit
18.02.2025 08:53понимается
Кем? :) Получается, на математичность влияет субъективный фактор — если человек не в курсе, что это выражение можно интерпретировать хотя бы двумя разными способами, то для него оно математическое, а для того, кто знает — не математическое.
И тогда получается, что математики видят в нем не математическое выражение, а не математики — математическое. Свой среди чужих, чужой среди своих. Забавно.
karavan_750
18.02.2025 08:53Кем? :) Получается, на математичность влияет субъективный фактор — если человек не в курсе, что это выражение можно интерпретировать хотя бы двумя разными способами, то для него оно математическое, а для того, кто знает — не математическое.
И тогда получается, что...
...Что ограниченность мышления даёт свои сайд-эффекты :)
ahabreader
18.02.2025 08:53Какой-то бред. Это как позвонить в Labcenter Electronics и объяснить им, сколько раз и где именно они нарушили ЕСКД.
Противопоставляет алгебру и арифметику советское пособие для педагогов. Оно утверждает, что в алгебре "знак умножения связывает компоненты действия сильнее, чем знак деления" (зависимо от того, опускается ли знак): a ÷ bc = a ÷ b*c = a÷(b*c). При этом само дальше эту сомнительную практику не использует и делит горизонтальной чертой.
В одних калькуляторах Texas Instruments решили повысить приоритет неявного умножения. На правила алгебры TI не ссылалась. Затем в следующих калькуляторах это решение откатили. В рунете повышение приоритета приписали некой алгебраичности калькулятора. Обосновывают тем пособием и ещё одним, противоречащим ему (пофиг, пляшем).
Общего правила в калькуляторах нет, один производитель в двух соседних моделях может поменять решение (TI-82 и TI-83), заучивать это не сильно полезнее, чем способы извлечения корня на арифмометре.
И подкину на эту тему:
На письме можно не дотянуть до конца черту корня: √ax, пусть гадают.
3*10^6 - это форма записи одного числа (то же, что 3e6) или выражение из нескольких чисел? От этого зависит результат выражения 1/3*10^6. Wolfram Alpha считает одним числом (но не с пробелами: 3 * 10^6), при обсуждении предыдущей статьи на это наткнулся.
Refridgerator
18.02.2025 08:53В одних калькуляторах Texas Instruments решили повысить приоритет неявного умножения
Я тоже так делал. А ещё ввёл оператор умножения с приоритетом ниже сложения, и с 2-мя дополнительными операторами делениями аналогично. Всё это для того, чтобы аргументы функции без скобочек писать можно было. Но вот операция возведения в степень ^ в эту стройную систему уже не вписалась, увы.
stanislavskijvlad
18.02.2025 08:53Имхо, человек - не робот, и мне запись a ÷ bc = a÷(b*c) кажется логичной. Но a ÷ b*c воспринимается как что-то отдельное. Хотя даже здесь, признаюсь, глазами b*c выглядит как целое, без скобок. Нам (людям) договориться бы один раз и всё.
sirri
18.02.2025 08:53Уж не помню где (то ли в книжках, то ли на обучающих сервисах-сайтах), но встречал фразу "а потом в процессе изучения мы с вами напишем простую программу-калькулятор" ;)
kos_s
18.02.2025 08:53Но в этих книжках же не писали, что этим простым калькулятором потом будет пользоваться кто-то еще.
qenoamej
18.02.2025 08:53Тоже такое проходил, только там не было скобок и даже запятых, только целые числа, сложение, вычитание, умножение, деление, ввод только с кнопок, без клавиатуры, только одна операция за раз.
И нельзя было выполнять действия над предыдущим результатом, только ввод новых целых чисел.
Насколько я понимаю, там нужно только ограничить количество вводимых цифр и количество цифр после запятой при делении.
DennisP
18.02.2025 08:53Эти калькуляторы из примеров или могут выполнять только по одному действию за раз, или полагаются на имеющийся в ЯП оператор eval или его аналог
S_WW
18.02.2025 08:53Фигнёй какой-то занимались все эти люди. Какое такое π? Пользователь не вводит на калькуляторе π, он вводит некие цифры. Вот сколько он их ввёл, с этим числом и будут выполняться вычисления. А вовсе не с числом π.
konst90
18.02.2025 08:53Пользователь может ввести именно pi, специальной кнопкой. А не набирать 3,141592...
p07a1330
18.02.2025 08:53Но у Пи в компе все равно же конечная точность?
anka007
18.02.2025 08:53Да, конечная. Но вы в курсе накапливаемой ошибки? Так что для констант, чтобы минизировать эту самую ошибку, точность должна быть весьма большой. А пи и е слишком часто встречающиеся константы при инженерных вычислениях.
S_WW
18.02.2025 08:53Значит надо взять на две цифры больше, чем требуется в результате. Собственно, так и построены все калькуляторы - у них обычно не меньше 6 цифр. А в инженерных расчётах требуется не больше трёх - да, представьте себе! 0.1% - такую точность обычно имеют хорошие измерительные приборы. Для особо точных может потребоваться четыре цифры. Вот поэтому шести цифр на калькуляторе за глаза хватает для любых расчётов. И поэтому данная статья - не более чем словоблудие!
netch80
18.02.2025 08:53Значит надо взять на две цифры больше, чем требуется в результате.
Рекомендуем таки прочитать статью.
Потому что именно сколько требуется в результате - там не фиксировано ни с написания кода калькулятора, ни даже с начала задания аргументов для расчёта.
discipuli
18.02.2025 08:530.1% на самом деле не такая уж и большая точность
То есть да, в классических инженерных расчётахт даже такая точность может быть избыточна, но например в каких нибудь научных расчётах или в определении времени это может быть критично, ближайший пример детектор гравитационных волн
anka007
18.02.2025 08:53Ближайший пример - расчет процентов по вкладу или налогам. 0.1% это вообще днище, а не точность. И это то, с чем сталкивается почти каждый человек. Пи в этом не участвует, но это такой маркер как разработчик вообще относится к точности расчетов.
Pshir
18.02.2025 08:53В статье же дан ответ на этот вопрос: зависит от конкретного выражения. sin(πn) даст в ответе точный ноль - в данном конкретном случае π фактически имеет бесконечную точность. А если считать π+e, например, то точность будет конечная.
p07a1330
18.02.2025 08:53Вы хотите сказать, что точность может превышать размерность разрядов, в которых число храниться?
Условно если под хранение Pi выделено 32 бита память, он в любом случае будет иметь точность не больше, чем +-100/(2^33)%
Даже если там применяется арифметика с плавающей запятойamphasis
18.02.2025 08:53Эх, если бы вы всё-таки прочитали статью, вы бы не задавали сейчас этот вопрос...
acsent1
18.02.2025 08:53Так у них π хранится в виде функции. Поэтому и точность у него любая заданная
Politura
18.02.2025 08:53У вас телефон - андроид? Если да, то запустите там калькулятор, нажмите на кнопку Пи, он вам покажет начало этого числа. Начните его листать скролля пальцем справа налево, когда долистаете до конца, скажете нам, какая там конечная точность :)
Keeper11
18.02.2025 08:53У меня показывает 10 знаков после запятой, и дальше не скроллится.
Politura
18.02.2025 08:53Вероятно производитель вашего телефона предустановил какой-то другой калькулятор вместо гугловского. У дочки Моторола moto g, у жены Гугл пиксель 7, на обоих в калькуляторе скроллится бесконечно, доскроллил до 1000+ знака за несколько секунд.
anka007
18.02.2025 08:53А если например умножить на 10 000 000 000? Разные калькуляторы по разному себя ведут
MATE Calculator из убунты
Pshir
18.02.2025 08:53Именно это я и хочу сказать. Числа можно представлять разными способами. Возьмём число 0.1 - у вас же нет сомнений, что я смог абсолютно точно записал это число? А в двоичном представлении записать точно его невозможно. Но двоичное представление не является единственно возможным. Даже внутри компьютера вы можете, применив мозги, хранить не только двоичные числа. Именно об этом и написана статья.
konst90
18.02.2025 08:53Зависит от реализации. Можно забить константу, а можно считать с потребной точностью. Об этом, собственно, и статья.
VBDUnit
18.02.2025 08:53Технически можно впихнуть её не в виде данных, а в виде алгоритма, который бесконечно наращивает её точность. т. е. нажал равно — результат появился и начинает бесконечно уточняться, прямо на экране. Чем дольше ждёшь, тем точнее результат. И так можно не с π, а вообще со всеми числами — выражение сначала упрощается, а затем итеративно вычисляется, наращивая точность, до бесконечности.
Если добавить возможность ставить на паузу вычисления уточнения и сохранять промежуточный результат на носитель, то получится калькулятор бесконечной точности.
WalterBeech
18.02.2025 08:53Никак не могу понять, для чего это нужно? Для чего может быть нужна точность π больше двух знаков после запятой? Если у калькулятора 6 разрядов, а в ответе все нули, а в седьмом — 1, то какая разница? Просто если первые 6 — нули, то выводить не "0.00000", а "0". Ну то есть как чисто теоретически интересная задача — написать идеальный калькулятор — я понимаю, а практически — для чего?
VBDUnit
18.02.2025 08:53интересная задача
This.
Вообще π может быть нужно с точностью больше 2 знаков, если мы делаем какую‑нибудь прецензионную втулку из рубина, у которой должна быть точность 1 атом. Да даже в пластины жестких дисков делаются с такой точностью, что двух знаков π явно мало, чтобы, например, рассчитать положение головки в полярных координатах.
Калькулятор, который «абсолютно точный и не косячит, гарантия 100%» может быть действительно полезным, но далеко, далеко не всегда в этом есть необходимость. Но это не значит, что её вовсе нет.
Кроме того, сам факт изучения вопроса «как сделать это очень точным» генерирует полезные знания и разные приёмы, которые могут помочь в тех местах, где практически нужно повысить точность или оптимизировать вычисления.
Иными словами, польза от таких задач косвенная, а не прямая. Мы генерируем некоторый интеллектуальный капитал, который целиком или частями можно потом использовать в других, более практических задачах.
WalterBeech
18.02.2025 08:53Ок, насчёт винчестеров и т. п. — согласен. Но нужно ли это для калькулятора в ширпотребном устройстве за 15к рублей...
anka007
18.02.2025 08:53Пи - это маленькая часть вычислений вообще, просто маркер отношения разработчиков к тому, что делает их программа. А в маленьком устройстве нормальные вычисления еще более актуальны, потому что в профессиональном профессионалы скорее всего будут нормально считать, считаясь с техническими ограничениями, а вот любительские примеры легко уйдут в середине в какой-нибудь overflow, хотя итог мог бы быть вполне валиден.
Zenitchik
18.02.2025 08:53Для чего может быть нужна точность π больше двух знаков после запятой?
Чтобы после десяти действий накопленная ошибка округления всё ещё позволяла отличить эллипс от гиперболы.
a-tk
18.02.2025 08:53Для чего может быть нужна точность π больше двух знаков после запятой?
Например, для траекторных вычислений космического аппарата в миссии на спутник Юпитера.
Pshir
18.02.2025 08:53Представьте, что у вас в ответе на задачу возникла разность вида (π-3.14). Как вы думаете, 0 и 0.00159265... - это разные числа? Вам бы хотелось их отличать друг от друга?
Pshir
18.02.2025 08:53У Гугловского калькулятора есть режим инженерного калькулятора. И пользователь (я, например) не просто может ввести число π, он это регулярно делает. Зачем кому-то может понадобиться вводить вместо π некие цифры? Это и требует больше нажатий, и даёт заведомо неверный результат.
S_WW
18.02.2025 08:53Нажатие кнопки π приводит лишь к тому, что это конечное число цифр вводится калькулятором. Но оно от этого не перестаёт быть конечным.
Politura
18.02.2025 08:53Нет, в андроид калькуляторе число Пи (как и другие иррациональные числа) можно листать бесконечно, оно будет дорассчитываться налету.
Fancryer
18.02.2025 08:53У меня в Redmi 9 нельзя листать бесконечно, результат - 3,14159265.
DaemonGloom
18.02.2025 08:53Родной калькулятор в Samsung - ограничен 3,1415926536. Гугловский - бесконечен.
Pshir
18.02.2025 08:53А вы не пробовали прочитать и понять статью, под которой вы комментарии оставляете? Или ваше изучение математики в школе остановилось в 6 классе?
m_chrom
18.02.2025 08:53Еще когда читал статью в оригинале, задумался над вопросм "А зачем это нужно было гуглу?". В чем смысл стрелять из пушки по воробьям, тратя дорогущее время топового специалиста (который потом вовлек еще двоих такого же уровня) на калькулятор, который 99% пользователей используют чтобы поделить чек в кафе?
Ну, допустим, есть еще школьники с чуть более сложными вычислениями. Но все равно кажется, что описанное выше - это чудовищный оверкилл.Pshir
18.02.2025 08:53Я бы просто радовался, что всё ещё есть люди, у которых есть желание и возможность сделать, как следует, а не как обычно. В наше время, когда школьники уже даже калькулятором разучиваются пользоваться и спрашивают ответ у произвольной LLM, это особенно ценно.
m_chrom
18.02.2025 08:53Это само собой! С точки зрения примера как основательно человек решал задачу, история максимально впечатляющая.
greefon
18.02.2025 08:53Есть два вида чудовищного оверкила:
Потратить очень много времени очень компетентного специалиста на написание идеального кода.
Потратить очень мало времени очень малокомпетентного специалиста и с помощью переиспользования кода быстро получить "рабочее" решение.
В одном случае вы получите идеальный калькулятор, например. Во втором ОС весом в десятки гигабайт, которая не делает ничего принципиально отличающегося от более ранних ОС, весом на порядки меньше.
Я, конечно, сильно упрощаю и с точки зрения бизнеса, наверняка, очень не прав. Но первый оверкил как-то симпатичнее.
m_chrom
18.02.2025 08:53Согласен, симпатичнее. Но между этими оверкиллами есть и промежуточные решения.
У меня вообще нет никаких вопросов к Бёму. Наверняка он получил кучу фана от процесса. Я, возможно, тоже на его месте так закопался бы (если бы умел делать это так же круто, как он).
Мне скорее интересна точка зрения его условного менеджера, у которого суперстар девелопер месяц пилит калькулятор для андроида, чтобы в нем можно было поделить Пи на корень из е с произвольной точностью. Как он обосновывает эти затраты.
greefon
18.02.2025 08:53Промежуточных решений не бывает. Бывают решения, удовлетворяющие ТЗ, и не удовлетворяющие. А вот ТЗ уже могут быть сформулированы "промежуточно".
Что касается Бёма, то он занимался проблемой "калькулятора" задолго до прихода в Гугл, еще будучи сотрудником SGI (а затем HPE).
Constructive Reals Calculator
Constructive Real ArithmeticTogether with Corky Cartwright, Vernon Lee, and others, I explored practical implementations of "exact" real computer arithmetic. Numbers are represented exactly internal to the computer, in a form that allows evaluation to any requested precision for display. This resulted in several papers and a sequence of implementations, including a Java one. It served as the basis of the more recent work on arithmetic in Google's Android calculator.
Хотелось бы узнать, конечно, откуда ноги растут, но, возможно, это был его пет-проект, доведенный до ума в гугле.
Vytian
18.02.2025 08:53Отцы-основатели Брин с Пэйджем -- математики в поколеньях, так что в давние времена империи добра оно было естественно. Ну или может их собственные финансы исчисляются с использованием той же библиотеки? Гугола денег у гугла, наверно, пока еще не предвидится, но когда считаешь свои деньги, даже одна мысль о принципиальной неточности гложет.
m_chrom
18.02.2025 08:53Ну или может их собственные финансы исчисляются с использованием той же библиотеки?
Возможно, им просто нужно было как-то считать долг перед российскими телеканалами )))
alamat42
18.02.2025 08:53ИМХО, это вполне оправдано, с учетом того, что андроид имеет миллиарды пользователей. Если представить, что всего 1% пользователей считает на нём что-то сложнее, чем базовые операции, то 1% от миллиарда - это уже 10 млн людей.
В общем, при таких масштабах аудитории кск будто бы имеет смысл потратить время специалистов на то, чтоб вылизать функционал базового софта, в том числе покрывая редкоиспользуемые кейсы.
sic
18.02.2025 08:53Это в сущности не сильно сложнее, чем заметка, это описывающая. В прочем, можно ещё куда проще - символьная оптимизация дерева вычислений (любое a x n + a x m равно a x (n+m) , при этом a мы считаем символом и даже не вычисляем, a^n/a^m = a^(n-m), и набор подобных правил) и трактовка последнего разряда любого вычисленного числа, как фантомного (любое x.000000000n равно x). Никто бы не придрался, если использовать 80 bit float. Контрпример можно придумать, но сложно и не особо нужно.
vkni
18.02.2025 08:53Но все равно кажется, что описанное выше - это чудовищный оверкилл.
Это самый распространённый калькулятор на планете. Фактически любая ошибка в нём будет гадить десяткам тысяч людей.
Если смотреть с точки зрения корпорации и прибыли - вы правы. Если смотреть с точки зрения "пользы для людей", это правильное применение сил, главное потом этот калькулятор не менять. :-)CitizenOfDreams
18.02.2025 08:53Это самый распространённый калькулятор на планете. Фактически любая ошибка в нём будет гадить десяткам тысяч людей.
Программист, нарисовавший интерфейс калькулятора для Win10: ваще пофиг.
Скрытый текст
netch80
18.02.2025 08:53Вклад 1) в общее впечатление от гугла и андроида, 2) в мировую математику. Создание впечатления у тех, кто немного больше понимает, и тем самым хотя бы лёгкое склонение их на свою сторону.
WalterBeech
18.02.2025 08:53Вот-вот. И это та компания, которая на собеседовании задаёт специально вымученные вопросы про блендер, чтобы убедиться, что кандидат не будет делать over-thinking.
yrub
18.02.2025 08:53а как надо было? дать задачу джуну и обкакаться в сми, что калькулятор только чашки кофе считать может, а более сложная школьная математика ему не по зубам? гугл технологическая компания, у которой сложные алгоритмы на многие вещи, байтики в json другие перекладывают.
и то что они сделали кстати не является чем-то сверхъестественным, мой калькулятор похожие фокусы делал, а я в старших классах не мог понять как это он после всех логарифмов, корней и степеней выдает правильные ответы без округлений и погрешностей.
LightSUN
18.02.2025 08:53задумался над вопросм "А зачем это нужно было гуглу?"
Потому что гугл нанимает лучших профессионалов, а они [иногда] любят делать лучшее возможное решение.
anoldman25
18.02.2025 08:53Добавлю /поправлю.
Конструктивные числа на самом деле это видимо вычислимые числа. См. википедию
https://ru.wikipedia.org/wiki/Вычислимое_число
Статья хилая, лучше смотреть английскую версию: https://en.wikipedia.org/wiki/Computable_number
А еще лучше книгу "Верещагин Н. К., Шень А. — Лекции по математической логике и теории алгоритмов. Часть 3. Вычислимые функции — М.: МЦНМО, 1999 "
Поучительное чтение, но требует некоторых мозговых усилий.
P.S. Скачал из интернета, но там не хватает по крайней мере нескольких страниц в начале. Может печатная книга лучше? Не знаю.
P.P.S. Похоже я ошибся. Но есть еще издание 2008, лучше наверное его почитать.
Insaned
18.02.2025 08:53Как-то так получилось что у меня установлено три приложения калькулятора для Linux - все три не сговариваясь дали правильный ответ на это (10^100) + 1 - (10^100)
lazbaphilipp
18.02.2025 08:53Ну если решение Бёма обнародовано, то уж кто-кто, а OS решения его точно у себя имплементируют.
codecity
18.02.2025 08:53Надеюсь, теперь вы больше будете ценить калькулятор в Android!
А вот что интересно. Ни в Android ни в iOS - не смогли сделать такую полезную штуку - как повтор последней операции при повторном нажатии на "=". А ведь часто такое нужно в быту, гораздо чаще чем супер-точность. А MS - смогли это сделать, молодцы.
Причем сделать это не так уж тривиально на самом деле.
blind_oracle
18.02.2025 08:53У меня в Самсунге S21+ вполне повторяет во встроенном калькуляторе. Но, возможно, он не ванильный Андроидный...
Asterris
18.02.2025 08:53А как советский инженерный калькулятор считал и синусы и экспоненты в те годы, когда ещё не придумали IEEE для плавающей запятой?
Zenitchik
18.02.2025 08:53Форматы с плавающей запятой придумали сильно раньше, чем один из них был закреплён стандартом IEEE. И они были разные.
netch80
18.02.2025 08:53Вот вам исторический список только форматов представления плавучки: http://www.quadibloc.com/comp/cp0201.htm. Зацените разнообразие подходов и размеров.
А ещё есть вопросы требований к вычислениям. IEEE754 требует для арифметики и рекомендует для функций - округление после как бы бесконечно точного результата. (На самом деле 1-2 младших бита, ULP, постоянно страдают - вот свежак про это. Но это таки начиная с sin() и для более сложных функций.) А раньше на это заметно поплёвывали.
S/360, S/370, и их аналоги ЕС-10xx в родной плавучке (в современных доках она зовётся HFP, hexadecimal floating point) вообще усекали все числа в операциях, а сама HFP прыжками по 4 бита вместо 1 ещё больше портила. При переходе на них с 7090, 7094 стояли плач и скрежет зубовный. И ничего, на этом производились серьёзные расчёты... надо было, конечно, чуть серьёзнее учитывать погрешности операций, чем сейчас. В 1968-м был массовый отзыв на переделку, потому что в двойной точности не было вообще guard digit, и на вычитаниях с умножениями точность была неприлично низкой - IBM модернизировала все блоки. PDP-11 имела 2 защитных бита там, где надо 3, неуправляемое округление, не имела INF. Мы-то уже видим готовенькое, но научная и инженерная мысль тут развивалась чудовищно медленно.
Те, кто профессионально занимаются вычислительной математикой всех видов, по крайней мере знают (их учили) про основные риски и методы их преодоления. Но тема неисчерпаема...
Melichrone
18.02.2025 08:53Можете подсказать. Не нашел приведенной книги на русском, на английском боюсь не осилю. А в целом, как человеку, изучавшего математику только в школе, можете посоветовать хорошие книги, по которым можно было бы углубиться в эту тему. Возможно для начала что-то по проще. А то я даже не знаю с чего начать
stanislavskijvlad
18.02.2025 08:53Вот вам замечательный сайт:
https://old.mipt.ru/online/#search.php?embedded=1
И в частности: http://j90428as.beget.tech/course/Maths-RingsAndFields-15L.html
SlFed
18.02.2025 08:53Кроме двух иррациональных констант ( пи и е ) есть еще Фи или Золотая Пропорция. Как его выразить на таком калькуляторе ? Надо еще одну кнопку добавить.
friend001002
18.02.2025 08:53Это они изобретали велосипед, чтобы на мобилках работало быстро? Раз дали пользователю возможность вводить подобные выражения, то почему их не считать давно написанными и протестированными библиотеками символьных вычислений?
zzzzzzzzzzzz
18.02.2025 08:53Во многой мудрости много печали; и кто умножает познания, умножает скорбь.
sirri
А это что же тогда? https://habr.com/ru/articles/883028/
PatientZero Автор
Неполный перевод оригинала
sirri
Так Вы бы где-нибудь в начале это указали.
PatientZero Автор
Да, добавил комментарий
Xobotun
Спасибо вам за полный перевод. Вашу версию ещё и читать приятно; в той я регулярно глазами о шероховатости спотыкался. :)
PatientZero Автор
Спасибо)