Калькулятор должен показывать результат математического выражения, которое вы ввели, и это намного, намного сложнее, чем кажется. То, что я собираюсь вам рассказать, — это величайшая история о разработке приложения-калькулятора. Взгляните на калькулятор iOS. Что-нибудь заметили? Он показывает неверный результат. (10^100) + 1 − (10^100) равно 0, а не 1. В Android всё правильно. И история о том, как это произошло, совершенно безумна.

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

Даже для него это, должно быть, было непросто. Цель приложения-калькулятора — давать вам правильные ответы. Числа с плавающей запятой неточны — они не могут представлять 0,3 или 10^100. Это означает, что калькулятор, основанный на числах с плавающей запятой, подобен дому, построенному на песке.

Это стоит повторить: чтобы давать правильные ответы на математические выражения, калькулятор должен представлять числа. И почти все числа не могут быть представлены в формате IEEE с плавающей запятой. Даже простые операции с числами с плавающей запятой требуют тщательного обдумывания для получения точного ответа.
Например, алгоритм суммирования Кэхана значительно уменьшает численную погрешность при сложении последовательности чисел с плавающей запятой конечной точности, по сравнению с обычным (наивным) подходом. Алгоритм работает за счет того, что поддерживает отдельную "бегущую компенсацию" (running compensation) - переменную, которая накапливает маленькие ошибки. Это фактически позволяет увеличить точность суммы на величину точности компенсационной переменной.
Первое решение: большие числа
Некоторых проблем можно избежать, если использовать большие числа. Большинство числовых типов всегда занимают 2 или 4 байта. Но не большие числа. Это целые числа без ограничений. Они занимают столько памяти, сколько нужно. Это решает проблему с примером (10^100) + 1 - (10^100). Но большие числа — это целые числа. А как насчёт дробей?

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

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

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

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

Поэтому Бём начал изучать «рекурсивную вещественную арифметику» (RRA). Если у вас есть выражение и вы знаете, насколько точным должен быть ответ, RRA даст вам ответ с точностью не ниже заданной.
Конструктивные вещественные числа — это числа, которые вы можете вычислять всё точнее и точнее. Вы никогда не сможете назвать мне все десятичные дроби числа π. Но если я попрошу вас назвать рациональное число в пределах 0,01 от числа π, вы можете назвать мне 3,14. Число π находится в пределах 0,01 от числа 3,14, так что это правильный ответ.

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

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

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

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

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

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

Их решение было абсолютно верным. Авторы разработали полуалгоритм, который сначала сводит проблему к проверке эквивалентности элементарных констант, а затем решает её. Особенность алгоритма в том, что он всегда даёт правильный ответ при завершении и гарантированно завершается, если только задача не содержит контрпример к гипотезе Шануэля.
Звучит идеально. Но есть одна проблема. Алгоритм слишком медленный. 1 не равно 1 - e^(e^(-1000)). Но чтобы алгоритм Ричардсона и Фитча это обнаружил, потребовалось бы больше шагов, чем атомов во Вселенной. Калькулятор на Android должен работать быстрее.
Они поняли, что это не конец света, если они показывают «0,000000...» в случае, когда ответ равен ровно 0, хотя это и не идеальный пользовательский опыт. Они просто не могут показать «0» в случае, когда ответ равен 0,0000001.
RRA даёт вам всю мощь конструктивных вещественные чисел, но недостатком является то, что получение точных ответов становится невозможным. Рациональная арифметика даёт точные ответы, но не может выразить π. Можно ли объединить их сильные стороны?
Всё это и много другое — ТГ «Математика не для всех»
Комментарии (97)
andreybrylb Автор
16.02.2025 18:02Ошибся в превью, спасибо!
Ziptar
16.02.2025 18:02Не в превью, а в формулировках.
Он показывает неверный результат. (10^100) + 1 − (10^100) равно 0, а не 1.
Это два разных предложения. В первом заявляется, что "он" (калькулятор) показывает неверный результат, второе утверждает, что значение выражения равняется нулю.
Они вместе не утверждают, что калькулятор на ios выдаёт для выражение значение 0, когда должен бы выдавать 1. Об этом приходится догадываться.Lazhu
16.02.2025 18:02Просто предложение с вычислением построено криво. Утверждение верно, если оно описывает вычисление на калькуляторе айфона, дающем неверный результат, но неверно в общем случае.
Ziptar
16.02.2025 18:02В имеющейся конструкции оно не описывает вычисление на калькуляторе айфона ¯_(ツ)_/¯
KabirK
16.02.2025 18:02Он показывает неверный результат: (10^100) + 1 − (10^100) [у него] равно 0, а не 1, [как должно быть].
двоеточие вместо точки и, для страховки, дополнения в квадратных скобках, — и всё бы читалось однозначно. а с точкой — без разницы, какое превью: второе предложение из цитируемых утверждает чепуху, извините.
CBET_TbMbI
16.02.2025 18:02Вообще интересно. По идее можно создать калькулятрр с человеческой логикой. Который будет складывать и умножать в столбик по одной цифре, как это делают люди. Который будет различать рациональные числа от иррациональных. Который будет сначала сокращать выражения, а потом уже считать. Который будет знать, что стремящееся к числу никогда не станет самим этом числом.
Moog_Prodigy
16.02.2025 18:02Который будет складывать и умножать в столбик по одной цифре, как это делают люди
Я такое чисто по приколу делал еще лет 30 назад) По сути работаем с цифрами как с символами, в роли арифметики - простой поиск по таблице. То есть вообще не используя арифметику машины и языка программирования.
Но эта штука хоть и позволяла работать с числами длиной миллионы знаков, была до жути медленной, ОЗУ жрало как не в себя, собственно куда такое можно применить, я и не нашел. Тоже бесило, что даже компуктер с его мегабайтами памяти не может мне посчитать дофигазначное число (этот факт бесил еще со времен первых калькуляторов, да!).
Wesha
16.02.2025 18:02В Ruby есть тип
BigDecimal
, который псевдостроковой и работает именно «по школьной математике» (умножение/деление «в столбик» и т. п.)
Sau
16.02.2025 18:02Можно пытаться решить (или хотя бы попробовать) проблему про числа-палиндромы, она же проблема 196. https://ru.wikipedia.org/wiki/Проблема_196
ahabreader
16.02.2025 18:02Можно считать численно, можно символьно. Это очень давно делают, MATLAB Symbolic Math Toolbox в 1993 вышел.
sym('10^100 + 1 - 10^100')
sena
16.02.2025 18:02если бы калькулятор показал 0 для e^(-10000), это было бы неправильно. Это не 0. Должно быть 0,00000... и вы можете прокручивать, пока не увидите первую цифру.
Можно же выдать просто 1.135483865E−4343. Разве это так трудно?
Для Андроида смогли написать калькулятор. Шок-контент без смс...
Politura
16.02.2025 18:02Написано что это перевод, а ссылки на оригинал нет, просто интересно, оригинал с Медиума? Я несколько лет назад от него отписался, после того как вконец достало, что там все статьи в топе про то как какой-нибудь популярный язык всенепременно умер, и прочую хрень типа "величайший", "безумный", а текст читаешь, вполне все заурядно, если повыкидывать все ахи и вздохи.
zvic
16.02.2025 18:02huder
16.02.2025 18:02Оригинал с твиттера, на этом сайте выше просто развернутый тред. Там же была опечатка с этой формулировкой про 0 и 1, где все подумали что 0 это правильно – на что автор сказал, что он просто опечатался, а в тредах менять уже нельзя нормально корневой твит даже с синей галкой. Но переводчик, не включив логику, взял и перевел с этой же опечаткой как есть, что вызвало те же самые вопросы, что и в твиттере.
nerudo
16.02.2025 18:02Пора ему взяться за питон:
import math
math.sin(math.pi)
1.2246467991473532e-16ahabreader
16.02.2025 18:02Нет.
from sympy import * print(sympify('sin(pi)'))
nerudo
16.02.2025 18:02Это не спортивно. sympy даже во встроенные библиотеки не входит.
PSprint(sympify('10**100+1-10**100'))
1
print(sympify('10**100+1-0.1*10**101'))
0ahabreader
16.02.2025 18:02Так получился бы не спорт, а терроризьм. Питон делает именно то, что от него просят. Если нужен более удобный доступ к символьным вычислениям, то надо его просить, не ломать существующий код.
print(type(math.pi)) print(type(math.sin(math.pi))) print('{0:.70f}'.format(0.1 + 0.2)) # <class 'float'> # <class 'float'> # 0.3000000000000000444089209850062616169452667236328125000000000000000000
PS: надо послушать тех, кто умеет ей пользоваться. Вижу, что фиксится через
, rational=True
ahabreader
16.02.2025 18:02Логика в том, что десятичная дробь триггерит переход к неточной плавающей запятой и эта же логика в MATLAB'е и Wolfram Alpha.
from sympy import * print(sympify('10^100 + 1 - 0.1*10^101')) # 0 print(sympify('10^100 + 1 - 1/10*10^101')) # 1 print(sympify('10^100 + 1 - 0.1*10^101', evaluate=False).simplify()) # 0 print(sympify('10^100 + 1 - 0.1*10^101', rational=True)) # 1 # MATLAB: # sym('10^100 + 1 - 0.1*10^101') # 0.0 # sym('10^100 + 1 - 1/10*10^101') # 1 # vpa('10^100 + 1 - 0.1*10^101', 100) # 1.0 # Wolfram Alpha https://www.wolframalpha.com/input?i=1+-+1%2F10*10%5E100 # 1 - 0.1*10^101 = -1*10^100 # 1 - 1/10*10^101 = 1 - 1/(10×10^100)
ahabreader
16.02.2025 18:02Мелкая ошибка: Wolfram Alpha распарсил
10*10^101
как одно число в научной нотации и целиком поместил в знаменатель, но слова про логику верны: у него1 - (1/10)*10^101 = -99999...
.С проблемой десятичных дробей, если они всё же нужны, борются "рационализацией" float'ов доступными средствами (sympy: [1][2][3], MATLAB: предлагают страдать).
unreal_undead2
16.02.2025 18:02Для меня тут самое удивительное не то, что Ханс залез в такие дебри, а то что человеку такого уровня дали писать калькулятор. Разве что сам сказал за пивом Брину с Пейджем "вы ничего не понимаете, только я сделаю правильно".
Lazhu
16.02.2025 18:02ВНЕЗАПНО
menz1
16.02.2025 18:02Местами поменяйте слагаемые, получите другой результат, есть разница в порядке вычисления
AlexMih
16.02.2025 18:02Вы так легко это говорите. По мне, нарушение коммуникативного закона сложения - куда более опасная вещь, чем потеря точности из-за ограниченной разрядной сетки. Пусть бы уже выдавало либо единицу, либо ноль, если уж не умеет столько разрядов обработать, но хотя бы единообразно. Потому что с ограниченной точностью в принципе понятно как работать, и в крайнем случае всегда можно сделать проверку "считать не буду, данные выходят за допустимый диапазон".
Но если оно от перестановки слагаемых сумму меняет, то это уже не калькулятор, а черт знает что.
menz1
16.02.2025 18:02Ну так вся статья об этом,и хоть и кратко, что если прибавить к большому числу маленькое, результат будет как если бы не прибавляли. Потому что калькулятор не занимается упрощением выражения, а считает слева направо. Теоретически, если перед вычислением побить на блоки по порядку чисел, можно немного нивелировать проблему, в реальности оно никому нафиг не надо, потому что никто не считает гугол в кубе плюс один.
atomlib
16.02.2025 18:02Не, это неинтересно — это ведь не сборщик мусора писал.
По тексту получается, что писал сборщик мусора: «Google нанял Ханса-Дж. Боэма, известного как „сборщик мусора Боэма“.» В оригинале речь идёт о том, что «Google hired Hans-J. Boehm, of the „Boehm garbage collector“ fame». То есть речь идёт про то, что человек заработал имя на сборщике мусора своего авторства.
Ну и дальше там постоянно признаки наспех выполненного машинного (или просто без любви к тексту и читателю) перевода:
Отсутствие проверки общеупотребительных терминов. В русской литературе его обычно называют «алгоритм Кэхана», но в англоязычной он известен как «Kahan summation algorithm». При дословном переводе получится как в тексте выше — «алгоритм суммирования Кэхана».
Было бы неплохо сделать прим. пер. и привести реальное имя Роберта Картрайта, а не просто его никнейм «Корки», как в оригинале. В любом случае, научные публикации ищутся по официальному имени.
Наконец, текст попросту переведён не до конца. Автор бросил переводить его на одном из твитов, сунул туда ссылку на свой канал в «Телеграме» и опубликовал перевод.
Возможно, случилось так потому, что всякие инструменты комбинации твитов в один длинный тред обрубают эту цепочку именно на этом твите. UnrollNow так делает. Лень ли это автора перевода или банальное головотяпство, но самая интересная часть осталась без перевода.
menz1
16.02.2025 18:02Угу, я тоже только попкорн достал... Резануло еще намного, что вместо рациональных и иррациональных чисел всякие другие слова )
Fr0sT-Brutal
16.02.2025 18:02Эти математические дебри, конечно, хорошо... Но лично мне куда больше бы пригодилась фича сохранения/извлечения числа из памяти, которая была в любом неплохом железном калькуляторе еще в 90-х, но до которой за 20+ лет существования Андроид так никто и не додумался >_< Или, например, 1/X - чего уж проще.
Grey83
16.02.2025 18:02Или, например, 1/X
Так есть же.
Вот, например, я кидал скриншот куркулятора от сяоми (емнип, можно ставить на любой смарт, лишь бы ведроид был подходящей версии):
https://habr.com/ru/articles/883028/comments/#comment_27933764Fr0sT-Brutal
16.02.2025 18:02Хорошо, это есть, а как насчет М+/-/R? Простейшие же, но очень нужные штуки. 1/Х еще можно заменить на ^-1, ладно, это суровый закон выживания - если не шаришь в алгебре за 7 класс, нечего тебе делать в калькуляторе (сарказм; ни за что не поверю, что факториал настолько часто востребован в штатном калькуле на телефоне), но уж работу с ячейкой памяти почему никто не делает?
Grey83
16.02.2025 18:02как насчет М+/-/R?
есть вот в этом калькуляторе (и в некоторых других встречал когда-то), что на скриншоте:
https://habr.com/ru/articles/883028/comments/#comment_27934282
Grad02
16.02.2025 18:02Какой бы крутой калькулятор не казался, а вот кнопок М+. М- и RM ну очень не хватает. В дешёвых китайских калькуляторах 1991 года уже были эти кнопки
Dr_Faksov
16.02.2025 18:02Вы знаете, я долго матерился на стандартный калькулятор от самсунга, в котором как раз не было кнопок М+. М- и RM. Которых ну очень не хватало. А потом, как-то, обратил внимание на значок, изображающий часы. А под ним - вся история вычислений с момента последней очистки. Можно повторно взять хоть результат, хот само выражение.
Может и в других калькуляторах стоит поискать?
Grad02
16.02.2025 18:02И история есть, и копипаста работает.
Но так удобно сначала вычислить одно выражение, положить его в память.
Потом поставить другое выражение, приплюсовать его к предыдущему (М+)
Потом третье и т.д.
Например, площади всех комнат.
Понятно, что можно разными способами выкрутиться, но М+ кнопка гораздо удобнее.
Grey83
16.02.2025 18:02HiPER Scientific Calculator имеет эти кноки (только результатом вычисления проблемного выражения у него тоже является ноль).
esaulenka
16.02.2025 18:02Ну, на любителя. Калькулятор, в котором можно вводить целое выражение, со скобками, гораздо удобнее на мой взгляд. Чтобы пользоваться памятью, надо порядок вычисления менять, это в уме не всегда просто сделать.
Grey83
16.02.2025 18:02калькулятор от линейки (под 13 ведроид, другие не пробовал) таки показывает единицу
kma21
(10^100) + 1 − (10^100) равно 0, а не 1
Я видимо не понимаю математику. К одному нечто прибавляется единица и вычитается такое же нечто. Почему получится ноль? Мы оперировали двумя одинаковыми сущностями и единицей. Одинаковые сущности взаимоуничтожились, куда делась единица?
CBET_TbMbI
Так автор пишет не про то, что это так, а про калькулятор айфона, который даёт такой ответ. Или, как минимум, про калькулятор айфона на тот момент времени. У кого айфон, проверьте, сейчас это так или нет?
pvsur
Ну не айфон... Hyper Calc Pro даёт 0... Вот тебе и гипер-про :(
Rio
И SpeedCrunch даёт 0, а вот калькулятор в Win 10 даёт 1. Вот уж не ожидал...
Advisory
Windows 11 тоже
Калькулятор
esaulenka
Блин, давайте я вам единицу хоть в сотую степень возведу, хоть в 100500-ю. В уме, безо всяких калькуляторов.
nikto_b
Дак не в степенях единицы суть (даже не в степени десятки)
Суть в том что вычисления много где - с плавающий запятой, что вызывает вот конкретно подобного рода проблемы как указано в статье
GNU Octave 6.4, к слову, в численном решении тоже выдаёт 0
si1v3r
Advisory выше возводит в степень не десять, а единицу, esaulenka видимо об этом.
ahabreader
А вы присмотритесь, там возводят именно единицу. И в двух других комментариях делают 10 XOR 100.
esaulenka
Нет, я как раз к тому, что единица в любой степени - всё ещё единица.
Что такое плавучка - я знаю. И что такое BigInt, тоже какое-то представление имею (даже вживую использовал. На 8-битном микроконтроллере были нужны 6-байтные числа. Потом выкинули эти велосипеды, взяли банальный uint64_t. Стало хотя бы читаемо).
А вот то, что в банальном калькуляторе с этой проблемой пытались бороться - не знал.
Advisory
Я вам больше скажу — на каждом инженерном калькуляторе есть кнопка [хʸ], но вместе с ней также есть кнопки [10ˣ], [x² ] и др. На первый взгляд кажется, что: если есть универсальная кнопка [хʸ] и используя ее можно ввести «любое число в любой степени (в том числе и в дробной)» — значит другие кнопки присутствуют для удобства ввода. А вот и нет! Дело в том, что математические операции, закрепленные за этими кнопками, осуществляются по разным алгоритмам. На маленьких числах это может быть не заметным, но на больших видно сразу.
Впервые эту особенность обнаружил на СССР-овских калькуляторах МК-61 и МК-52, чему был несказанно удивлен. И только уже позже, в институте, преподаватель объяснил, что операции на кнопке [хʸ] выполняются через функцию и поэтому получается некоторая погрешность, в отличие от других кнопок — на них точнее.
doryfish
Только что проверил. Айфон 15 Про даёт 0. Андроид 15 даёт 1. Круто!
OrtoXylene
мой калькулятор в Андроид 9 на данное выражение даёт ноль. Интересно.
mikemdr
В Андроид 13 (MIUI 14) калькулятор на данное выражение выдаёт 0.
happy234
13 андроид, но oneplus. Ответ 1
Bigdoc
А Андроид 12 (MIUI 14) дает 1
Grey83
А13 MIUI 14 с com.miui.calculator версии 12.3.77 выдаёт вот это (при добавлении скобок в выражение результат всё тот же):
Fil
Попробуйте не 1^100, а 10^100
Grey83
да, так 0 показал
noncinque
Android 13, OneUI 5.1, даёт 1.
toribasho
Причем 1 он выдаёт и при разных значениях степеней
А иногда и так
OneUI 6.1
Grey83
Если ничего не путаю, то результат должен был получиться
9.0E+99
Grey83
а не, всё правильно калькулятор показал
10^100 - 10^10
- это9.(9)E+100
k4ir05
Так вроде всё верно - 1 в любой степени будет 1.
s13nder
Странно, у меня Айфон 15 Про Макс дал результат 1
fxux
k4ir05
И что тут не так?
dopusteam
Так автор ж пишет (ну или переводчик переводит так)
И ниже на картинке 1 как раз, как будто это и есть неверный результат
CBET_TbMbI
Картинка из Андроида, про калькулятр которого и идёт речь в статье. Айфоновский просто для сравнения упомянут.
dopusteam
Автор уже поменял картинку
Явно ж не 'просто упомянут для сравнения', раз 'Взгляните'
dom1n1k
Ограничение точности чисел с плавающей точкой.
Если к очень большому числу прибавить очень маленькое, то большое "проглотит" маленькое не заметив его, потому что не хватило разрядной сетки.
Вместо айфона можете то же самое ввести в консоли браузера, тоже получится 0.
sena
$ echo '(10^100) + 1 − (10^100)' | qalc
(10^100) + 1 − (10^100) = 1
ЧЯДНТ?
yellowmew
А при чем здесь вы, как раз речь о том что в андроиде калькулятор нормально сделали. Это не значит что qalc должен тоже считать неверно. Хотя вон даже гугл выдает неверный ответ
Скрытый текст
и Яндекс
Скрытый текст
sena
> речь о том что в андроиде калькулятор нормально сделали
Это конечно достижение :) :) :)
Нобелевку ему!
Advisory
У меня по другому посчитал
Яндекс нейро калькулятор
VluDs
Так у вас через искусственный интеллект, там вообще другие принципы расчета.
yellowmew
у вас калькулятором послужила нейросетка яндекса
а у меня некий "обычный" калькулятор в поиске
Advisory
Знаю. Только это было не мое решения выбрать инструмент для расчета, а Яндекса. Я просто ввел в поисковую строку математическое выражение и нажал Enter.
В смысле, я имел ввиду, что у вас Яндекс и у меня Яндекс, а считает по разному.
Alexeyslav
Считают то они одинаково, только ИИ перед расчетом поменял приоритет операций, или можно сказать упростил выражение без его непосредственного вычисления. Если дать ему задачу сложнее, которую нельзя так просто упростить, он тоже посчитает неверно.
myvlink
edge и firefox ответили правильно
ahabreader
JS и C в этом плане удивительные языки, в них можно даже так писать:
/s /s /s
Скрытый текст
Возможно, первым шутить начал тот, кто добавил скобки вокруг крышечки, чтобы при xor'е тоже получался ожидаемый результат.
Aetae
В консоли используется js, возведение в степень там **. А ^ это битовый xor.:)
dom1n1k
В js это выглядит так:
10**100 + 1 - 10**100
Не обязательно даже брать настолько большие числа, достаточно таких:
1e+20 + 1 - 1e+20
woof_woof
а можно еще так
>10n**100n+1n-10n**100n
>1n
:)
idimus
Алгоритм "сортировочной станции", самый распространенный алгоритм для построения калькуляторов. Промежуточный результат вычислений чаще всего хранится в некотором числе. Тип этого числа, скорее всего, будет числом с плавающей запятой, и возможно двойной точностью.
А дальше начинается шаманская магия компьютерных чисел с плавающей запятой: они, условно говоря — дробь, и точность верхней и нижней части ограничена. Так вот, компьютер найдет ближайшее число к запрашиваемому, но оно не будет в точности равно тому числу, что мы хотим если точность не позволяет. Приблизительное правило следующее — чем дальше от 0, тем числа менее точны.
Так вот условные 10^100 в такое число помещаются, но там не то что 1, там даже 10 уже за пределами точности такого числа. И такая операция как плюс (или там минус), просто ни на что не повлияет.
Выходит что исходное число не поменяется, а два представления 10^100 для компьютера выглядят одинаково (к сожалению, даже это не всегда так). Но отсюда и получается 0.
Собственно говоря, статья и была о том, как этот неудобный фактик о числах с плавающей точкой обойти.
VaVM
Потому что числа с плавающей точкой - смотрите стандарт IEEE 754.