2024-03-13 09:08:08 +01:00

# dc ![](https://github.com/ceticamarco/dc/actions/workflows/dc.yml/badge.svg) [![CodeFactor](https://www.codefactor.io/repository/github/ceticamarco/dc/badge/master)](https://www.codefactor.io/repository/github/ceticamarco/dc/overview/master)

2023-11-02 17:25:24 +01:00

```
```

`**dc** is an advanced, scientific and programmable RPN desktop calculator with macro support (re)written in C++. `

2024-04-19 16:14:47 +02:00

`By default, dc supports a wide range of arithmetical, trigonometrical and numeric functions and `

`its capabilities can be further extended by writing user-defined programs using the embedded, turing-complete, macro system.`

2023-11-02 17:25:24 +01:00

```
```

2024-03-20 09:18:56 +01:00

`**dc** reads from the standard input, but it can also work with text files using the ``-f` flag. Furthermore, you can decide to evaluate an expression

2023-11-02 17:25:24 +01:00

`without opening the REPL by using the ``-e` flag.

```
```

`Operands are pushed onto the stack following the LIFO policy; operators, on the other hand, pop one or more values`

2024-03-20 09:18:56 +01:00

`from the stack and push back the result. By default, `**dc** is very quiet, in order to inquiry the stack you need to use one of the supported

2023-11-02 17:25:24 +01:00

`options(see below).`

```
```

`dc` can be invoked with the following command line options:

`````

2023-11-02 17:38:34 +01:00

`RPN desktop calculator with macro support. Usage: `

`-e, --expression `< EXPRESSION > | Evaluate an expression

`-f, --file `< FILE > | Evaluate a file

`-h, --help | Show this helper`

`-V, --version | Show version`

2023-11-02 17:25:24 +01:00

`````

```
```

`Some of the supported features are:`

- Basic arithmetical operations(`+`, `-` , `*` , `/` , `^` , `%` );

- Scientific notation support(`5e3` -> `5000` );

2024-04-19 16:14:47 +02:00

- Support for complex numbers(`-1 v` -> `(0,1)` );

2023-11-28 15:14:37 +01:00

- Trigonometrical functions(`sin`, `cos` , `tan` , `asin` , `acos` , `atan` );

2024-04-19 16:14:47 +02:00

- Base-10 logarithm(`y`);

2024-03-27 11:57:52 +01:00

- Statistical functions(permutations, combinations, summation, sum of squares, mean, standard deviation, linear regression);

2023-11-07 10:36:32 +01:00

- Base conversion(binary: `pb` , octal: `po` , hexadecimal: `px` );

2023-11-02 17:25:24 +01:00

- Factorial and constants(`!`, `pi` , `e` );

2024-03-14 15:54:50 +01:00

- Random number generator(`@`);

- Integer conversion(`$`);

2024-03-19 12:22:01 +01:00

- Bitwise operations(`{`, `}` , `l` , `L` , `m` , `M` );

2023-11-02 17:25:24 +01:00

- Stack operations:

2024-03-25 10:53:23 +01:00

` `- Print top element(`p`, `P` , `p.` );

2023-11-02 17:25:24 +01:00

` `- Clear the stack(`c`);

` `- Remove top element(`R`);

` `- Swap order of top two elements(`r`);

` `- Duplicate top element(`d`);

` `- Dump the whole stack(`f`);

2024-03-12 11:50:13 +01:00

` `- Last head, 2nd, 3rd element of the stack(`.x`, `.y` , `.z` );

2023-11-16 16:08:50 +01:00

- Parameters:

` `- Set precision(`k`);

` `- Set input and output radix(`i` and `o` );

2023-11-02 17:25:24 +01:00

- Registers:

` `- Store top element of the stack on register `X` (`sX` or `SX` );

` `- Load content of register `X` on top of the stack(`lX` or `LX` );

- Arrays:

` `- Store second-to-top of main stack into array `X` indexed by top-of-stack(`:X`);

` `- Pop top-of-stack and use it as an index for array `X` (`;X`);

- Macros:

` `- Define a new macro inside square brackets(`[ ]`);

` `- Executing a macro from the stack(`x`);

2024-03-13 11:04:39 +01:00

` `- Evaluate a macro by comparing top-of-head and second-of-head elements(`>X`, `<X` , `>=X` , `<=X` , `!=` where `X` is a register);

` `- Load external file(`'`).

2023-11-02 17:25:24 +01:00

```
```

`And much more. You can find the complete manual [`here ](https://github.com/ice-bit/dc/blob/master/man.md ).

```
```

## Installation

2024-03-12 15:34:14 +01:00

`dc` is written in C++20 without using any additional dependency. In order to build it, install [CMake ](https://cmake.org/ ), [Ninja ](https://ninja-build.org/ )

`and issue the following commands:`

2023-11-02 17:25:24 +01:00

````sh`

2024-03-12 15:34:14 +01:00

`$> cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release .`

`$> cmake --build build`

2023-11-02 17:25:24 +01:00

`````

2024-03-12 15:34:14 +01:00

`A new statically-compiled binary called ``dc` will be created in the `build/` directory. To generate a man page from the `man.md` document,

2024-02-13 16:39:55 +01:00

`use the following command(note: needs pandoc):`

2023-11-03 10:48:30 +01:00

````sh`

2023-11-03 11:57:19 +01:00

`$> pandoc man.md -s -t man > dc.1`

2023-11-03 10:48:30 +01:00

`````

```
```

2024-02-13 16:39:55 +01:00

`Otherwise, if you are running a Linux-based distribution, issue`

`one of the following commands:`

```
```

### Debian/Ubuntu:

````sh`

`$> sudo apt install ./dc-`< VERSION > .x86_64.deb

`````

```
```

### RHEL/Centos/Fedora

````sh`

`$> sudo dnf install ./dc-`< VERSION > .x86_64.rpm

`````

```
```

### Arch

````sh`

`$> sudo pacman -U dc-`< VERSION > -1-x86_64.pkg.tar.zst

`````

```
```

`You can find the binaries on the release page or on the ``bin` folder

`of this repository.`

```
```

2024-03-01 10:31:00 +01:00

## Unit tests

`This repository as well as the CI pipeline provides unit tests for the`

`program's features. To run them, issue the following command:`

```
```

````sh`

`$> ./utest.sh tests`

`````

2024-02-13 16:39:55 +01:00

```
```

2023-11-02 17:25:24 +01:00

## Usage

`dc can be used in three different ways:`

1. From the interactive REPL(run it without any argument);

2. By evaluating an inline expression, i.e.

` ```sh`

` $> dc -e "5 5 + p"`

` ````

3. By evaluating a text file, i.e.

` ```sh`

` $> cat foo`

` 2 4 - # Evaluate 2 - 4`

` 2 ^ # Evaluate x^2`

` p # Print the result(4)`

` $> dc -f foo`

` 4`

` ````

```
```

`Below there are more examples.`

```
```

1. Evaluate

`$$\frac{-5 + \sqrt(25 - 16)}{2}$$`

`````

`-5 25 16 - v + 2 / p`

`````

`where ``v` is the square root function

```
```

2. Evaluate

`$$\frac{.5 + .9}{3^4}$$`

`````

`.5 .9 + 3 4 ^ / p`

`````

```
```

3. Evaluate `10 + 5` inline(i.e. without opening the REPL):

````sh`

`$> dc -e "10 5 +"`

`````

```
```

4. Evaluate an expression from a file:

````sh`

`$> cat foo`

` 5 5 + `

` 2 d * v `

` f`

`$> dc -f ./foo`

`````

```
```

5. Evaluate

`$$\sin(2\pi) + \cos(2\pi)$$`

`````

`2 pi `* sin 2 pi * cos + p

`````

```
```

6. Swap top two elements using registers(you can also use the `r` command):

````sh`

`5 4 p # Load some values on the stack(output: 4)`

`sA sB # Pop values and store them into the registers 'A' and 'B'`

`lA lB # Push 'A' and 'B' content onto the stack`

`p # Print top element(output: 5)`

`````

```
```

2024-03-12 11:50:13 +01:00

7. Recall last value of top three elements of the stack:

````sh`

`10 1 / # `< - Wrong operation: division instead of sum

`.y # Call last value of y register`

`.x # Call last value of x register`

`+ p # Sum and print head(output: 11)`

`````

```
```

8. Print out numbers from 1 through user-defined upper bound:

2023-11-02 17:25:24 +01:00

````sh`

`[ p 1 + d lN >L ] sL # Print numbers from 1 through 'N'`

```
```

`[ Enter limit: ] P # Ask user for limit 'N'`

`? 1 + sN # Read from stdin`

`c 1 lL x # Clear the stack, add lower bound, load and execute macro`

`````

```
```

2024-03-12 11:50:13 +01:00

9. Sum the first 36 natural numbers(😈), i.e.,

2023-11-02 17:25:24 +01:00

`$$\sum_{i=1}^{37} i = 666$$`

````sh`

`$> dc -e "36 [ d 1 - d 1 `< F + ] d sF x p "

`````

```
```

2024-03-12 11:50:13 +01:00

10. Print the first 20 values of `n!` :

2023-11-02 17:25:24 +01:00

`````

`[ la 1 + d sa * p la 20 >y ] sy`

`0 sa 1`

`ly x`

`````

```
```

2024-03-12 11:50:13 +01:00

11. Compute the factorial of a given number:

2023-11-02 17:25:24 +01:00

`````

`[ ln 1 - sn ln la * sa ln 1 !=f ] sf`

`[ Enter value: ] P ? sn`

`ln sa`

`lf x`

`la p`

`````

```
```

2024-03-12 11:50:13 +01:00

12. Compute the sum $8AB6F + B783E$ in base 16. Print the result in base 10 and in base 2:

2023-11-16 16:08:50 +01:00

`````

`16 i`

`8AB6F B783E +`

`[ Result in base 10: ] P R p`

`[ Result in base 2: ] P R pb`

`````

```
```

2024-03-12 11:50:13 +01:00

13. Compute the Greatest Common Divisor(GCD) between two user-defined numbers `A` and `B` :

2023-11-02 17:25:24 +01:00

`````

`[ Enter A: ] P R ?`

`[ Enter B: ] P R ?`

`[ d Sa r La % d 0 `< a ] d sa x +

`[ GCD(A,B)= ] P R p`

`````

```
```

2024-03-12 11:50:13 +01:00

14. Compute the Least Common Multiple(LCM) between two user-defined numbers `A` and `B` :

2023-11-02 17:25:24 +01:00

`````

`[ Enter A: ] P R ? d sA`

`[ Enter B: ] P R ? d SA`

`[ d Sa r La % d 0 `< a ] d sa x +

`LA lA * r /`

`[ LCM(A,B)= ] P R p`

`````

```
```

2024-03-12 11:50:13 +01:00

15. Find the roots of a quadratic equation of the form:

2023-11-02 17:25:24 +01:00

`$$ax^2 + bx + c = 0$$`

```
```

`with $$a,b,c \in \mathbb{R}, a \neq 0$$`

```
```

`using the formula`

`$$x_{1,2} = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$`

```
```

````sh`

#!/usr/local/bin/dc -f

# GIVEN A QUADRATIC EQUATION OF THE FORM

# AX^2 + BX + C = 0

2024-04-19 16:14:47 +02:00

# COMPUTE ITS REAL OR COMPLEX ROOTS

2023-11-02 17:25:24 +01:00

# DEVELOPED BY MARCO CETICA 2023

`#`

2023-11-16 16:08:50 +01:00

`3 k`

2023-11-02 17:25:24 +01:00

`[ Enter A: ] P ? sA`

`[ Enter B: ] P ? sB`

`[ Enter C: ] P ? sC`

`lB 2 ^ 4 lA lC `* * - v sD

`lB -1 * lD - lA # NEGATIVE DELTA`

`2 * / sS # FIRST SOLUTION`

`lB -1 * lD + lA # POSITIVE DELTA`

`2 * / SS # SECOND SOLUTION`

2023-11-16 16:08:50 +01:00

`[ X1: ] P R lS p`

`[ X2: ] P R LS lS p`

2023-11-02 17:25:24 +01:00

`````

```
```

2024-03-14 15:54:50 +01:00

16. Generate $n$ (pseudo)random numbers from user-defined range:

`````

`5 k`

`[ lA lB @ p ] sR`

`[ Enter number of samples: ] P ? sN`

`[ Enter lower bound: ] P ? sA`

`[ Enter upper bound: ] P ? sB`

`[ lR x r 1 + d lN >=L ] sL`

`0 lL x`

`````

```
```

2024-03-19 12:22:01 +01:00

17. Estimate $\pi$ using Monte Carlo simulation:

2024-03-15 08:42:15 +01:00

`````

`10 k`

`[ 0 1 @ sX 0 1 @ sY ] sR`

`[ lX 2 ^ sX lY 2 ^ sY ] sQ`

`[ 0 ;A 1 + 0 :A ] sI`

`[ 1 lX lY + `< =I ] sC

`[ lR x lQ x lC x 1 + d lN >=L ] sL`

`0 0 :A`

`0 6500 sN`

`lL x 0 ;A lN /`

`4 * p`

`````

```
```

2024-03-20 09:18:56 +01:00

18. Convert a hex color to RGB:

2024-03-19 12:22:01 +01:00

`````

`16 i`

`[ Enter hex value: ] P R ? sV`

`lV FF { 0 :A # Blue`

`lV 8 M FF { 1 :A # Green`

`lV 10 M FF { 2 :A # Red`

2024-03-25 10:53:23 +01:00

`[ , ] sc`

`[ [ RGB( ] P 2 ;A P lc p. 1 ;A P lc p. 0 ;A P [ ) ] p. [ = ] p. lV ph ] x`

2024-03-19 12:22:01 +01:00

`````

```
```

2024-03-27 11:57:52 +01:00

19. Find the mean of the following temperatures(Celsius): `[25, 15, 9.5, 10, 20, 16, 20]` :

`````

`4 k`

`25 15 9.5 10 20 16 20`

`SX SX SX SX SX SX SX`

`gM p # Prints 16.5000`

`````

```
```

2023-11-02 17:25:24 +01:00

## License

```
```

`[`GPLv3 ](https://choosealicense.com/licenses/gpl-3.0/ )