Продвинутый научный калькулятор на Python своими руками
Хозяйке на заметку: изготовить мощный научный калькулятор можно всего одной строчкой кода для Bash.
Откройте файл .bashrc в своей домашней директории и внесите в него следующую строку:
alias calc='python3 -ic "from math import *"'
Перезапустите терминал. Для вызова калькулятора наберите calc.
calc
>>> x = ( sin(pi/6)*cos(pi/6) )**2 + sqrt(2/3)
>>> x
1.003996580927726
>>> x+x
2.007993161855452
>>> log10(x+x*5)
0.7798834842217774
Преимущества калькулятора:
- интуитивная очевидность синтаксиса;
- все основные математические функции;
- функциональность можно расширять практически неограниченно с помощью import;
- отличный справочник по функциям.
Мало? А что бы вы сказали, если бы была возможность совместить калькулятор с MatLab? Волшебство Linux-технологий позволяет и такое:
apt-get install ipython python-matplotlib
В .bashrc:
alias calc='ipython --pylab'
Теперь возможности «калькулятора» безграничны.
Комментарии
Чингачгук
23 сентября, 2015 - 20:59
Лучше сделайте обзор графических калькуляторов.
Чингачгук
23 сентября, 2015 - 22:43
гы
а потом сделай так:
calc
>>> 0.1+0.1+0.1-0.3
и насладись результатом
5.551115123125783e-17
>>>
comrade
23 сентября, 2015 - 23:10
Проверил мою маленькую коллекцию линуксовских калькуляторов.
"0" получился у
Genius Mathematical Tool,
SpeedCrunch,
Qalculate!,
Gcalctool.
Так же правильно посчитал bash:
echo 0.1+0.1+0.1-0.3|bc -l
0
LibreOffice Calc – тоже "0"
Других мнений (причём, разных:-) придерживаются
galculator,
GRPN,
extcalc,
MTAC.
pomodor
23 сентября, 2015 - 23:50
Нет правильного и неправильного. Разные программы по-разному хранят числа с плавающей запятой. Точнее, калькуляторы считают способом, который ожидаем владельцем калькулятора, а языки программирования устроены иначе. Вот, например, в Ruby:
irb(main):001:0> 0.2+0.1
=> 0.30000000000000004
И это ожидаемый для программиста ответ.
comrade
24 сентября, 2015 - 00:07
Вероятно, грамотные калькуляторы просто не делают из дроби 1/10 число с плавающей запятой :-)
pomodor
24 сентября, 2015 - 00:14
Делают. Как иначе можно в процессор запихнуть 1/10? Только перед выводом калькулятор скорректирует ответ, чтобы пользователь не охренел от неожиданности. А ЯП не скорректирует, так как ожидается, что уж программист-то должен понимать, откуда берется этот результат.
comrade
24 сентября, 2015 - 00:20
По-простому, можно – как во втором классе.
1/10 + 1/10 = (1 + 1)/10 = 2/10
(и никаких вещественных чисел, дробь – это два целых числа:-)
А в более сложных случаях есть всякие прикольные штуки, типа цепных дробей и прочего.
Вычисления с абсолютной точностью – это отдельный раздел вычислительной математики.
pomodor
24 сентября, 2015 - 00:34
В регистр процессора вы как 1/10 засунете? В целочисленный это не влезет, а FP-регистр может терять несколько последних бит при определенных обстоятельствах, описанных в статье по ссылке выше.
comrade
24 сентября, 2015 - 00:43
2/7 + 3/5 =
= 2*5/7*5 + 3*7/5*7 =
= 10/35 + 21/35 =
= (10+21)/35 =
= 31/35
Что-то типа...:-)
pomodor
24 сентября, 2015 - 00:49
Думаю, мне не нужно напоминать, что сия конструкция сразу нае...нётся, как только промежуточным результатом вычислений окажется иррациональное число? ;)
comrade
24 сентября, 2015 - 00:54
Ну, в вещественном регистре иррациональное число тоже будет себя чувствовать, как рыба об лёд:-)
Можно операции классифицировать – при каких могут иррациональные числа возникать, при каких – не могут...
Соответственно, и вычисления производить.
pomodor
24 сентября, 2015 - 00:55
Правильно. Теперь возвращаемся к вашему высказыванию: "грамотные калькуляторы просто не делают из дроби 1/10 число с плавающей запятой".
comrade
24 сентября, 2015 - 01:03
Не вижу предмета для спора. Эту задачу можно решать и через целые числа, и через вещественные (используя дополнительный контроль точности).
Это достаточно очевидно.
pomodor
24 сентября, 2015 - 01:12
Напомню тогда о предмете. Вы сказали: "грамотные калькуляторы просто не делают из дроби 1/10 число с плавающей запятой". Готов поспорить. Мое мнение: грамотные калькуляторы любые числа хранят в FP-регистрах. Даже результат вычисления 1+1. Просто потому, что следующей операцией может быть извлечение квадратного корня, например.
comrade
24 сентября, 2015 - 04:01
Вообще-то операция в процессоре по вычислению корня от вещественного числа – приближённая.
И "FP-регистра" для хранения чисел высокой точности не хватит (о чём Вы же в одном из комментариев ниже и написали:-). Так что число высокой точности хранится в целочисленных массивах, которые содержат мантиссу или порядок, либо числитель и знаменатель простой дроби, либо члены цепной дроби. В зависимости от реализуемых алгоритмов.
Иррациональные числа, как раз наиболее эффективно приближаются именно цепными дробями.
И т.д., и т.п.
В общем, мораль сей басни: простой калькулятор, который 0.1+0.1+0.1-0.3=[что-то там] – это действительно не сложно и очевидно.
А, при росте требований по точности и представлению результата, всякой интересной математики и алгоритмов задействуется всё больше.
Я не вижу смысла спорить – что там целое, а что вещественное.
С настоящими вещественными и иррациональными числами могут работать только системы компьютерной алгебры.
pomodor
24 сентября, 2015 - 00:00
Ну и культовая статья на эту тему: «What Every Computer Scientist Should Know About Floating-Point Arithmetic». Кстати, это один из вопросов, которые задают на собеседовании, чтобы сразу отфильтровать говнокодеров.
Чингачгук
5 октября, 2015 - 16:06
А вот в калькуляторе Windows такого нет! Значит, Windows лучше! Шах и мат, господа линуксоиды! :)
jtad
5 октября, 2015 - 16:46
и не говори, так облажались. Виндовозный калькулятор самый калькуляторный в мире. Пойду венду ставить...
pomodor
24 сентября, 2015 - 00:04
А где здесь Bash? Это отдельная программа bc (An arbitrary precision calculator language) посчитала, а Bash только передал данные через конвейер.
comrade
24 сентября, 2015 - 00:35
Согласен!
Кстати, bc не просто "баш-калькулятор", а
«a language that supports arbitrary precision numbers with interactive execution of statements» –
интерактивный алгебраический язык с числами произвольной длины.
pomodor
24 сентября, 2015 - 00:39
bc — это не Bash Calculator. Это Basic Calculator. К слову, bc появился задолго до появления не только Bash, но и Linux.
comrade
24 сентября, 2015 - 00:45
Опять согласен:-)
А "числа произвольной длины" Вас не смутили?
pomodor
24 сентября, 2015 - 00:52
А почему меня должно было это смутить? Там есть внутренняя переменная scale, которой можно задать требуемую точность вычислений (цифр после запятой). И эта точность зависит только от объема ОЗУ на компе. Всё честно.
Чингачгук
26 сентября, 2015 - 08:32
А extcalc кто-нибудь пробовал. Он есть в AUR.
comrade
26 сентября, 2015 - 09:23
Да, я его упоминал уже(-:
Extcalc:
0.1+0.1+0.1-0.3=-1.35525271560688054e-20
А так, интересный калькулятор (по возможностям), добавлен у меня в коллекцию.
Но мне не показался особенно удобным.
Да и его проект выглядит не особенно живым уже лет шесть.
Sunrise
17 октября, 2015 - 11:56
Не проще ли использовать irb или встроенный функционал bash, например:
echo "$((14+17))"
dk
17 октября, 2015 - 12:33
$(( ))
не умеет нецелые числа. Тогда уж bc лучше, как уже предлагали вышеcomrade
17 октября, 2015 - 13:08
А как будет выглядеть пример из статьи
(sin(pi/6)*cos(pi/6) )**2 + sqrt(2/3)
на irb?
pomodor
17 октября, 2015 - 17:46
Только не на irb, а на Ruby. irb — название программы-интерпретатора (Interactive Ruby). Будет так:
include Math
(sin(PI / 6) * cos(PI / 6)) ** 2 + sqrt(2.0/3)
comrade
17 октября, 2015 - 18:05
...Что, конечно же, в разы проще чем вариант из статьи (-;
______________
Анекдот в тему (математический:-)
Вовочка принёс пару по математике.
Отец его ругает:
-Что на этот раз, дебил?!
-Ну, математичка спросила - "Сколько будет 3+2"
-А ты, дебил, не знаешь?!
-Я сказал - пять.
-Ну, правильно, и что?
-А она спросила - "А сколько будет 2+3"
-А это не один ху..?!
-Ну я так и сказал!
pomodor
17 октября, 2015 - 18:57
Пардон, а куда еще проще? ИМХО, смысл не в том, чтобы сократить запись до курьезного минимума, а в том, чтобы освоенный синтаксис пригодился где-то еще. И очень хорошая идея в том, чтобы начать с «калькулятора», продолжить изучение языка и в итоге освоить программирование.
Комментировать