Калькулятор командной строки, который сохраняет дробные значения

Вопрос или проблема

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

Согласно его man странице:

Все числа представлены
внутренне в десятичном формате, и
все вычисления выполняются в десятичном формате. (Эта версия усечет
результаты
от операций деления и умножения.)

Можете ли вы предложить эквивалент bc для Ubuntu Maverick? Мне нужно выполнять сложные вычисления в командной строке с переменными.

Вы можете установить длину дробной части с помощью scale=n.

Команда echo 'scale=20;752/447' | bc дает:

1.68232662192393736017

Обратите внимание, что даже если число помещается в пределах масштаба, могут быть добавлены дополнительные нули:

scale=20
1/2
.50000000000000000000

К сожалению, всегда существует проблема округления:

scale=50
1/3*3
.99999999999999999999999999999999999999999999999999

calc (я верю, из пакета apcalc) делает то же самое, что и bc, но не округляет. Он отображается аналогично bc, но в отличие от bc, он понимает научную нотацию. Пример:

> calc
Калькулятор произвольной точности в стиле C (версия 2.12.3.3)
Calc является открытым программным обеспечением. Для получения подробной информации о лицензии наберите: help copyright
[Наберите "exit" для выхода или "help" для помощи.]

; a=234
; b=a/7
; b
    ~33.42857142857142857143
; c=b/1e20
; c
    ~0.00000000000000000033
; c*1e10
    ~0.00000000334285714286
; 

Сравните с bc:

> bc -l
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
Это бесплатное программное обеспечение без АБСОЛЮТНОЙ ГАРАНТИИ.
Для получения подробной информации наберите `warranty'. 
a=234
b=a/7
b
33.42857142857142857142
c=b/10^20
c
.00000000000000000033
c*1e10
(standard_in) 6: ошибка синтаксиса
c*10^10
.00000000330000000000

Небольшой поиск дает много результатов, не все из которых имеют отношение, но я уверен, что несколько проб приведут вас именно к тому, что вам нужно (например, wcalc):

aptitude search calc
i   apcalc                               - Калькулятор произвольной точности (оригинальное название: calc)
i A apcalc-common                        - Калькулятор произвольной точности (общие файлы)
p   apcalc-dev                           - Библиотека для арифметики произвольной точности
p   bandwidthcalc                        - калькулятор времени передачи файлов, написанный на GTK+
p   calcoo                               - Научный калькулятор (GTK+)
p   calcurse                             - текстовый календарь и менеджер дел
p   concalc                              - консольный калькулятор
p   extcalc                              - многофункциональный научный графический калькулятор
p   gcalcli                              - Интерфейс командной строки Google Calendar
i   gcalctool                            - Калькулятор рабочего стола GNOME
p   ipcalc                               - калькулятор параметров для адресов IPv4
p   ipv6calc                             - маленькая утилита для манипуляции адресами IPv6
p   kcalc                                - калькулятор для KDE 4
p   keurocalc                            - универсальный конвертер валют и калькулятор - двоичный пакет
p   keurocalc-data                       - универсальный конвертер валют и калькулятор - пакет данных
p   lcalc                                - программа для вычислений с L-функциями
p   libcolor-calc-perl                   - Модуль Perl для простых операций с RGB цветами
p   libdate-calc-perl                    - Библиотека Perl для доступа к датам
p   libdate-pcalc-perl                   - Модуль Perl для вычислений даты по григорианскому календарю
p   libmath-basecalc-perl                - Конвертация чисел между различными системами счисления
p   libmath-calc-units-perl              - Человекопонятный калькулятор с учетом единиц измерения
p   libmath-calculus-differentiate-perl  - Алгебраический механизм дифференцирования
p   libmath-calculus-expression-perl     - Алгебраические инструменты класса выражений
p   libmath-calculus-newtonraphson-perl  - Алгебраическая реализация метода Ньютона-Рафсона
p   libticalcs-dev                       - Библиотека для связи с калькуляторами Texas Instruments [файлы разработки]
p   libticalcs2-7                        - Библиотека для связи с калькуляторами Texas Instruments
p   libwww-google-calculator-perl        - Perl интерфейс для калькулятора Google
p   octave-physicalconstants             - предоставляет значения физических констант в Octave
i   openoffice.org-calc                  - офисный пакет для повышения производительности -- электронные таблицы
v   openoffice.org2-calc                 -
p   python-ipcalc                        - выполнение вычислений подсетей IP
v   python2.6-ipcalc                     -
p   r-cran-epicalc                       - Калькулятор эпидемиологии GNU R
p   rpncalc                              - RPN-калькулятор, пытающийся эмулировать HP28S
p   science-numericalcomputation         - Пакеты вычислительной науки Debian
p   sipcalc                              - Расширенный консольный калькулятор подсетей ip
p   subnetcalc                           - Калькулятор подсетей IPv4/IPv6
p   sugar-calculate-activity             - вычисление активности для графической оболочки Sugar
p   tapecalc                             - полноэкранный редактор ленты, который позволяет пользователю редактировать вычисления
p   transcalc                            - калькулятор микроволновых и радиочастотных линий передачи
p   wcalc                                - Гибкий научный калькулятор командной строки
p   wmcalclock                           - dock.app, который просто показывает время и дату
p   xsmc-calc                            - Калькулятор Smith Chart для X

Я бы предложил использовать Python в качестве калькулятора командной строки:

$ python
>>> from math import *
>>> help(sin)
    sin(x)

    Возвращает синус x (измеряемый в радианах).

Также я бы рекомендовал IPython или IDLE. Оба сильно улучшают удобство использования стандартной оболочки.

Обновление: используйте python3, чтобы избежать неприятных сюрпризов с усечением:

$ python2.7

>>> 10/3
3

$ python3

>>> 10/3
3.3333333333333335

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

Если вам нужен точный калькулятор, вам нужна символическая система, такая как maxima.

Кстати, bc поддерживает переменные.

“genius” является самым продвинутым калькулятором из доступных, с вариантами как командной строки, так и графического интерфейса. Ознакомьтесь с руководством для получения подробной информации, и смотрите http://www.jirka.org/genius.html.

Для установки просто введите:

sudo apt-get install genius gnome-genius

Вот хороший вариант:

spigot — командный калькулятор точных вещественных чисел

Если у вас установлен octave, вы можете использовать его в командной строке следующим образом:

octave --silent --eval 752/447

Чтобы сократить запись, вы можете добавить следующее как псевдоним в .bashrc

alias ose="octave --silent --eval"

а затем вызывать его как ose 752/447. Псевдоним/ярлык произвольный, но вам нужно перезапустить терминал, чтобы он заработал.

Вы можете установить octave с помощью:

sudo apt-get install octave

Конечно, с octave вы можете использовать и все продвинутые функции, доступные в нем.

Я только что сделал простой:

https://github.com/jb55/ratio-cli

$ ratio <<< '14/15 * 3'
14/5 

Настройки для использования Python в качестве калькулятора использованы в моем пакете calcpy.

По сути, он использует хуки IPython для замены любого числа на Rational из sympy:

import ast
from sympy import Rational, init_printing

class ReplaceFloatWithRational(ast.NodeTransformer):
    def visit_Constant(self, node):
        if isinstance(node.value, float):
            return ast.Call(func=ast.Name(id='Rational', ctx=ast.Load()),
                            args=[ast.Call(func=ast.Name(id='str', ctx=ast.Load()),
                                           args=[node], keywords=[])],
                            keywords=[])
        return self.generic_visit(node)

class ReplaceIntegerDivisionWithRational(ast.NodeTransformer):
    def visit_BinOp(self, node):
        def is_integer(x):
            if isinstance(x, ast.Constant) and isinstance(x.value, int):
                return True
            if isinstance(x, ast.UnaryOp) and isinstance(x.op, (ast.USub, ast.UAdd)):
                return is_integer(x.operand)
            if isinstance(x, ast.BinOp) and isinstance(x.op, (ast.Add, ast.Sub, ast.Mult, ast.Pow)):
                return is_integer(x.left) and is_integer(x.right)
            return False

        if (isinstance(node.op, ast.Div) and is_integer(node.left) and is_integer(node.right)):
            return ast.Call(func=ast.Name(id='Rational', ctx=ast.Load()),
                            args=[node.left, node.right], keywords=[])
        return self.generic_visit(node)

get_ipython().ast_transformers.append(ReplaceFloatWithRational())
get_ipython().ast_transformers.append(ReplaceIntegerDivisionWithRational())
init_printing()

Пример:

In [1]: 1/2 + 2/3
Out[1]: 7/6

Это преобразует все числа в дроби, в calcpy числа выводятся как в дробях, так и в десятичных.

Ответ или решение

Командная строка калькулятора с поддержкой дробных значений

Если вы ищете командную строку калькулятора для Ubuntu, который позволяет выполнять расчёты с дробными значениями и минимизирует потерю точности, у вас есть несколько достойных альтернатив. Рассмотрим наиболее заметные варианты.

1. Использование bc с настройками масштаба

Калькулятор bc уже знаком многим пользователям Linux, и он способен работать с переменными и дробными числами. Вы можете задать длину дробной части, используя команду scale=n. Например:

echo 'scale=20; 752/447' | bc

Это возвращает результат с 20 цифрами после запятой:

1.68232662192393736017

Однако следует отметить, что bc также сталкивается с проблемой округления. Например:

echo 'scale=50; 1/3*3' | bc

Результат будет:

.99999999999999999999999999999999999999999999999999

Хотя bc поддерживает переменные, оно всё же может округлять результаты, что делает его непригодным для высокоточных расчётов.

2. Калькулятор calc

Калькулятор calc, который можно установить с помощью пакета apcalc, представляет собой продвинутый калькулятор с поддержкой дробных значений, который также не округляет результаты:

calc

Пример работы с переменными:

; a=234
; b=a/7
; b
    ~33.42857142857142857143

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

3. Python как калькулятор

Возможно, наилучший выбор для тех, кто ищет больше функциональности и точности, — это использовать Python. Он позволяет выполнять операции с дробными значениями без потери точности, начиная с Python 3:

python3
>>> 10/3
3.3333333333333335

Более того, вы можете использовать библиотеки, такие как sympy, для более точного представления дробей:

from sympy import Rational
Rational(1, 2) + Rational(2, 3)  # Возвращает 7/6

4. Калькулятор octave

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

octave --silent --eval 752/447

Для удобства вы можете создать алиас в вашем файле .bashrc:

alias ose="octave --silent --eval"

5. Альтернативные инструменты

Существуют и другие утилиты, которые могут соответствовать вашим требованиям:

  • Genius: продвинутый калькулятор с графическим интерфейсом и командной строкой. Устанавливается через:
    sudo apt-get install genius gnome-genius
  • Maxima: для символических вычислений.
  • Spigot: предназначен для выполнения точных вычислений с вещественными числами.

Заключение

Выбор калькулятора зависит от ваших конкретных потребностей: если вам нужна высокая точность и многофункциональность, Python и его библиотеки — это оптимальный выбор. Если вам нужен быстро настроенный инструмент для простых вычислений, calc и bc подойдут, но с ограничениями на поддержку точности. Каждый из перечисленных решений имеет свои преимущества и недостатки, и выбор подходящего инструмента может существенно упростить вашу работу с расчётами в командной строке.

Оцените материал
Добавить комментарий

Капча загружается...