- Python 97.5%
- Makefile 2.5%
| tests | rework some error checking | |
| .gitignore | ||
| .pre-commit-config.yaml | ||
| dc.py | rework some error checking | |
| Makefile | type check the test code too | |
| pyproject.toml | oops actually cover tests | |
| README.md | update README.md | |
dc in Python
dc is a classic Unix arbitrary-precision RPN calculator.
While standard dc implementations inherently support working in various input and output bases, GNU dc and BSD dc always operate internally in decimal mode.
That is, all numbers are internally represented as m * 10^e for some integer mantissa m and signed exponent x.
Additionally, the treatment of the scale for non-decimal input and output bases is problematic, especially in GNU dc.
This implementation of dc uses arbitrary precision fractions of the form n/p for integers n and p.
That means that this dc implementation can correctly show 1/3 or 1/2 in base 3:
pydc> _99k 3o
pydc> 1 3 / pc
.1
pydc> 1 2 / pc
_
.1
For positive scale, the maximum denominator maxden is |obase|**scale. For negative scale, the maximum denominator is |scale|. Otherwise, iterated calculations can encounter unreasonably large denominators. The denominator-limit algorithm uses round-to-nearest, not round-to-zero as dc.
Number display depends on scale and obase:
- If
obaseis negative, the number is printed as a fractiona b /with the numerator and denominator in base|obase|. - If
obaseis positive andscaleis negative, the number is converted to a (possibly repeating) fraction in the output base. The repeating part is shown with an over-bar. If the fraction is too long, it is truncated with "..." and the repeating part is not noted. - Otherwise, the number of output figures is chosen so that the base raised to the power of the number of post-"decimal"-point digits in the printed value is less than the denominator of the true value. A number printed in this way is truncated toward zero, not properly rounded.
In particular, you can do hex arithmetic like
pydc> _4096k 16 d i o # or GiGo
pydc> .8 .FFE * pc
0.7FF
and always get the correct number of figures.
The square root operation v is performed by first scaling the number by maxden**2, taking the truncating integer square root yielding an integer r, then returning the fraction r / maxden.
This has the effect of giving an answer with the proper number of digits past the radix point, though it is doubly truncated and this probably can affect the correctness of the last digit in some cases.
Invoking dc.py
python dc.py (or just ./dc.py) to enter the pydc REPL. Uses readline for history & editing. In Python 3.13+, _pyrepl is used which allows multiline entry and syntax highlighting.
python dc.py -e 'expression' to directly evaluate an expression and exit.
python dc.py -e 'expression' -i to directly evaluate an expression, then enter interactive mode. This might be useful for instance to set the radix and scale: python dc.py -e '16dio 8k' -i to start in hexadecimal with 8 digits to the right of the radix point.
python dc.py file, python dc.py < file or command | dc.py: fancy readline features are not enabled when stdin is not a terminal.
Missing features
dc extensions from FreeBSD dc are not implemented.
! (shell command) is not implemented.
Extensions
Ouptut base and scale can be negative, affecting printed number representation as explained above.
The letter G is accepted as a digit with a value of 16. Thus, GiGo selects base 16 for input and output, no matter the current input base.
Interactivity
The pydc prompt shows:
- The number of stack elements in square brackets
- Information about the current input radix, output radix, if different than default. This is shown as dc code, so that pasting the sequence shown into a fresh pydc setting would recreate the settings. (Note: this means that the values are always shown in base 10!)
When multiline editing is available, the results of the currently input program is shown as you type.
Testing
make test runs the unit tests. Many of them compare to the system dc. make coverage runs coverage testing. make mypy does type checking.
Contributing
Human contributions are welcome, but code review is not guaranteed to be timely. Issues without associated pull requests are unlikely to be operated on. AI contributions are not accepted at this time.