Manipulation with dc Macros: An Expert Guide
How to Work with Macros
In this example, we'll explore how to use macros with the dc
command to manipulate and print characters.
Macros are a powerful feature in dc
that allow you to define sequences of commands for reuse.
To print the character 'e', we can create a macro and execute it as follows:
dc -e '[101P]sa lax'
So it wont be possible to simply execute
dc -e "lax"
Explanation:
[101P]sa
: This portion of the command defines a macro that does the following:[101P]
: Pushes the ASCII value 101 (which corresponds to 'e') onto the stack.-
sa
: Stores the defined macro in register 'a'. -
lax
: This part of the command loads and executes the macro stored in register 'a', which will result in the character 'e' being printed.
Now, let's take a look at how various commands in the dc
language can be used to print different characters:
dc Command | Sentence |
---|---|
lHA | 'H' |
lax | 'e' |
lbx | 'l' |
lcx | 'l' |
ldx | 'o' |
lex | ' ' |
lfx | 'w' |
lgx | 'o' |
lhx | 'r' |
lix | 'l' |
ljx | 'd' |
dc Command | Digits |
---|---|
lHA | '10' |
These commands demonstrate how to use dc
to manipulate and print characters by defining and executing macros. You can create custom macros to handle various tasks and calculations in the dc
language.
dc Command | Uppercase |
---|---|
lAA | 'A' |
lBA | 'B' |
lCA | 'C' |
lDA | 'D' |
lEA | 'E' |
lFA | 'F' |
lGA | 'G' |
lHA | 'H' |
lIA | 'I' |
lJA | 'J' |
lKA | 'K' |
lLA | 'L' |
lMA | 'M' |
lNA | 'N' |
lOA | 'O' |
lPA | 'P' |
lQA | 'Q' |
lRA | 'R' |
lSA | 'S' |
lTA | 'T' |
lUA | 'U' |
lVA | 'V' |
lWA | 'W' |
lXA | 'X' |
lYA | 'Y' |
lZA | 'Z' |
dc Command | Lowercase |
---|---|
laa | 'a' |
lba | 'b' |
lca | 'c' |
lda | 'd' |
lea | 'e' |
lfa | 'f' |
lga | 'g' |
lha | 'h' |
lia | 'i' |
lja | 'j' |
lka | 'k' |
lla | 'l' |
lma | 'm' |
lna | 'n' |
loa | 'o' |
lpa | 'p' |
lqa | 'q' |
lra | 'r' |
lsa | 's' |
lta | 't' |
lua | 'u' |
lva | 'v' |
lwa | 'w' |
lxa | 'x' |
lya | 'y' |
lza | 'z' |
dc Command | Digits |
---|---|
l0a | '0' |
l1a | '1' |
l2a | '2' |
l3a | '3' |
l4a | '4' |
l5a | '5' |
l6a | '6' |
l7a | '7' |
l8a | '8' |
l9a | '9' |
dc Command | Special |
---|---|
lsca | ' ' (space) |
ldota | '.' |
lcommaa | ',' |
lexcla | '!' |
lquosa | '"' |
laposa | ''' |
llbra | '[' |
lrbra | ']' |
llpara | '(' |
lrpara | ')' |
lhasha | '#' |
lampera | '&' |
lplusa | '+' |
lminusa | '-' |
lslasha | '/' |
lbacksla | '\' |
lquesta | '?' |
latra | '@' |
lastera | '*' |
lperca | '%' |
lcola | ':' |
lsemia | ';' |
lltbra | '<' |
lgtbra | '>' |
lequala | '=' |
lcara | '^' |
ltildea | '~' |
lundera | '_' |
lpipa | ' |
dc Command | Character |
---|---|
lnewlinea | 'n' (newline) |
ltaba | 't' (tab) |
lcura | '^' (caret) |
ldolara | '$' (dollar) |
lgrava | '`' (backtick) |
lpipea | ' |
ltildea | '~' (tilde) |
lbracka | '{' (brace) |
lrbracka | '}' (right brace) |
llesstha | '<' (less than) |
lgreatha | '>' (greater than) |
lequala | '=' (equal) |
lperca | '%' (percent) |
lplusa | '+' (plus) |
lminusa | '-' (minus/hyphen) |
lslasha | '/' (forward slash) |
lbacksla | '\' (backslash) |
lquesa | '?' (question mark) |
lexcla | '!' (exclamation mark) |
latra | '@' (at symbol) |
lhasha | '#' (hash) |
lampera | '&' (ampersand) |
lastera | '*' (asterisk) |
lsemia | ';' (semicolon) |
lcola | ':' (colon) |
lcommaa | ',' (comma) |
lperiosa | '.' (period) |
laposa | ''' (apostrophe) |
lquosa | '"' (quotation mark) |
llpara | '(' (left parenthesis) |
lrpara | ')' (right parenthesis) |
llbra | '[' (left bracket) |
lrbra | ']' (right bracket) |
lltbra | '<' (less than) |
lgtbra | '>' (greater than) |
lequala | '=' (equal) |
lcara | '^' (caret) |
lundera | '_' (underscore) |
ldota | '.' (dot) |
lbackticka | '`' (backtick) |
Execute Commands
Print H+$\(!p!\),
dc -e '72dP [101-72+dP]sa [108-101+dP]sb [108-108+dP]sc [111-108+dP]sd [32-111+dP]se [119-32+dP]sf [111-119+dP]sg [114-111+dP]sh [108-114+dP]si [100-108+dP]sj lax lbx lcx ldx lex lfx lgx lhx lix ljx'dc -e '0sI [72]sA0 [101]sA1 [108]sA2 [108]sA3 [111]sA4 [32]sA5 [87]sA6 [111]sA7 [114]sA8 [108]sA9 [100]sA10 [lAIsI lAI 1+ dsi 11<M]dsMx lI0<M'
Print same as above with x' above
dc -e '72dP [101-72+dP]sa [108-101+dP]sb [108-108+dP]sc [111-108+dP]sd [32-111+dP]se [119-32+dP]sf [111-119+dP]sg [114-111+dP]sh [108-114+dP]si [100-108+dP]sj lax lbx lcx ldx lex lfx lgx lhx lix ljx'
Print Hello World
in uppercase in each first string
dc -e '[72P]sa [101P]sb [108P]sc [111P]sd [32P]se [87P]sf [114P]sg [100P]sh lax lbx lcxlcx ldx lex lfx ldx lgx lcx lhx'
dc -e '[72P]sa [101P]sb [108P]sc [111P]sd [32P]se [87P]sf [114P]sg [100P]sh lax lbx lcx lcx ldx lex lfx ldx lgx lcx lhx 32P'
Print HELLO WORLD ###
with spaces between the words as desired.
dc -e '
[#]P[#]P
[#]P32P
[H]P[E]P
[L]P[L]P
[O]P32P
[W]P [O]P[R]P
[L]P[D]P32P'
And in a oneliner
dc -e '[#]P[#]P [#]P32P [H]P[E]P [L]P[L]P [O]P32P [W]P [O]P[R]P[L]P[D]P32P'
Use manual instead of apt, rtfm! // Patrik
dc -e "16i[q]sa[ln0=aln100%Pln100/snlbx]sb557365206D616E75616C20696E7374656164206F66206170742C207274666D21202F2F2050617472696Bsnlbxq" |rev
Direct Stack Manipulation (reversed
)
You can push the ASCII values onto the stack in reverse order and print each one. This approach directly manipulates the stack
echo '100P 108P 114P 111P 87P 32P 111P 108P 108P 101P 72P' | dc
95P = _ 94P = ^ 50 = 2
Using Macros for Each Character
dc -e '[72P]sa [101P]sb [108P]sc [111P]sd [32P]se [87P]sf [114P]sg [100P]sh lax lbx lcx lcx ldx lex lfx ldx lgx lcx lhx 32P'
Incremental ASCII Print
You can start from a base character and incrementally add to it, printing along the way
dc -e '72dP 29d+P 7d+P 0d+P 3d+P 21d+P 55d+P 24d+P 3d+P 6d+P'
Script Example
Solving Complex Equations with dc
Let us illustrate how the desktop calculator can be adeptly employed for complex calculations. Consider the following equation:
\(p(x|y) = \frac{p(y|x)p(x)}{p(y)}\)
\((10 J) / (196 * x^2) = 4 kW/s\)
\(√, √2, √[n](), √[3]{x^3+y^3/2}\)
Firstly, we need to convert 4 kW/s to joules per second:
4 kW = 4000 J/s
Thus, the equation becomes:
(10 J) / (196 * x^2) = 4000 J/s
Now, let's solve for x^2
:
x^2 = (10 J) / (196 * 4000 J/s)
And then take the square root to find x
.
We will use dc
to accomplish this:
dc -e '10 196 4000 * / v p'
This script performs the following steps:
10 196 4000 * /
computes(10 / (196 * 4000))
, which gives usx^2
.v
computes the square root of the result.p
prints the output.
If this yields 0, it could be due to the very small value of x^2
. To address this, try increasing the precision in dc
. Add the k
command at the beginning of the script to set the precision. For example:
dc -e '10k 10 196 4000 * / v p'
Here, 10k
sets the precision to 10 decimal places. Test this to see if it yields a more reasonable result for x
.
Other examples
$ = dc -e '[1060P]sa lax'
! = dc -e '[1057P]sa lax'
[:space:] = dc -e '[1056P]sa lax'
\n = dc -e "[#]12P lax"
dc -e "[15]p[#]98P lax"|xargs|sed 's/ //g'