[Question]
  [
What general tips do you have for golfing in [dc](https://en.wikipedia.org/wiki/Dc_(computer_program))? 
dc is a calculator utility for UNIX/Linux that predates the C language. I am interested in how to make my dc programs (calculations?) shorter. I'm looking for ideas that can be applied to general [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") that are at least a little bit specific to dc (eg. removing comments is not a helpful answer)
Please post one tip per answer.
  
[Answer]
# Arrays
Although they're a headache for beginners, `dc` offers arrays. They work like this:
```
value index :a    # store `value' in array linked to top of stack `a', with index `index'
      index ;a    # push a[index] on (main) stack
```
As usual, the first element has the index 0. Arrays can be useful when working with sequences, like in the [SUDSI sequence](https://codegolf.stackexchange.com/questions/48155/generate-the-sudsi-sequence/81164#81164 "Generate the SUDSI sequence"), especially in combination with counters. Arrays can reduce the amount of number-shuffling you need to do (and the number of counters and comparisons) if you want to select a particular element without destroying your environment. For example, if you want to move a stackful of numbers into an array, you could write a recursive function that uses `z` (stack depth) or `z 1-` as the index, stores the element, and checks whether `z == 0` to terminate itself.
```
[z 1- :a z 0 !=F]dsFx    # or I could just write such a function for you :)
```
Be aware of the following:
* Arrays are associated with instances on named stacks. If you push a new value on a stack that has an array associated with it, that array will also be "pushed back", and a "new" array will take its place. The old array won't be usable until the corresponding value on the named stack is also usable (i.e., on top of its stack). This is a complicated concept that would be better explained with a good animation, which is beyond me.
* You **can** store stuff in a named array without actually pushing a value into the corresponding named register. However, if you do this, you **cannot** access the stack/register with that name for the rest of the session. `dc` will crash.
* If you pop a value off a named stack, any values in the corresponding array will be lost—no warnings, no safeguards, nothing. Just gone (which can also be useful).
[Answer]
# If-then-else statements
Suppose we want to check the condition `a==b` (let `a` and `b` be stored in their respectively-named registers).
edit:
```
[         # Everything is wrapped in one big macro
  [         # An inner macro for our *then* part
              # <-- Stuff to execute if a==b here
  2Q          # Then quit the inner and outer macro
]sE       # `E' is for Execution register ;)
la lb =E  # if a==b, execute E
          # if E is executed, it will quit the whole macro, so the rest is never reached:
          # <-- Stuff to execute if a!=b here
]x        # End macro; Execute
```
Let `(foo)` be a placeholder, for the purpose of condensing:
```
[[(then)2Q]sE(condition)E(else)]x
```
Pretty sure this is the most compact if statement possible (also featured [here](https://codegolf.stackexchange.com/questions/44680/showcase-your-language-one-vote-at-a-time/57145#57145)).
[Answer]
# You can save input with `d`
By using `d`, which duplicates the ToS (top of stack) you can move the input out of the way for later use, while still being able to use it.
[Answer]
# 0 to the nth power instead of conditionals/macros
Sometimes you might need something like [c](/questions/tagged/c "show questions tagged 'c'") ternary conditional:
```
A == B ? C : D;
```
A nice way to handle this is described in [@Joe's answer](https://codegolf.stackexchange.com/a/84327/11259). However we can do better:
```
0AB-^E*C+
```
where E is D - C.
This tests for equality by raising 0 to the power of the difference of the two values. This results in 1 if equal and 0 otherwise. The rest just scales the 1 or 0 to the values C or D. This works because `dc` gives 00 = 1 and 0n = 0 for n != 1.
[Answer]
Sometimes it is necessary to discard a number from the stack. One way to do this is to simply pop it into an unused variable, i.e. `st`. However in some situations, you can pop it to a couple of other places, e.g. the input base when you have no more numerical input or to the precision specifier if you don't have any more operations to do where precision would make a difference. In the former case, use `i`. In the latter case, use `k`.
[Answer]
# Length Calculation: `Z`, `X`, and `z`
`Z` pops the ToS and pushes the number of digits (decimal) if it's a number or the number of characters if it's a string. This can be useful for detecting the length of a result (for buffering output) or computing string length. Note that for numbers, `Z` pushes the combined length of the integer part and the fraction part.
`X` pops the ToS and pushes the number of digits in the fraction part of the number. If the ToS was a string, `0` is pushed.
To find the number of digits in the integer part of the number, one might use `dZrX-`. If you haven't changed the precision from the default `k==0`, using `1/Z` is shorter, but suppose you need to maintain a particular non-zero precision after the operation: `Kr0k1/Zrk` is rather an eyesore.
`z` pushes the number of items on the stack. One of my favourite commands, it does not actually pop any values! It could be used to generate a sequence of numbers or increment a counter. Using `zd` repeatedly (say, at the start of a macro) could let one [test a calculation](https://codegolf.stackexchange.com/a/90618/54071) on each natural or whole number in ascending order.
[Answer]
Digits `A` to `F` may be used in substitution for the numbers 10 to 15. However they must still be treated effectively as base 10 digits (assuming input base is 10) when in different places. In other words, with input base 10 `FF` would not represent 255, it would represent `(15 * 10) + 15` or 165. 
In fact this works for all digits `0` to `F` in any input base `2` to `16`. So if the input base is 5, then `26E` would be `(2 * 5^2) + (6 * 5) + 14`, or 94.
Note this behaviour is in effect for the unmodified GNU sources. However, as @SophiaLechner points out, RedHat-based distros appear to use [bc-1.06-dc\_ibase.patch](https://src.fedoraproject.org/rpms/bc/blob/f8/f/bc-1.06-dc_ibase.patch) which changes this behaviour so digits >= ibase are treated as `ibase - 1`, regardless of their actual value. Note the TIO `dc` [appears not to have bc-1.06-dc\_ibase.patch](https://tio.run/##S0oszvj/PzmxREE/tSRZPy01Jb8oUbcoNSc1sTiVKyVZQTdV3c2tQP3/fwA) (even though its Fedora 28 ¯\_(ツ)\_/¯ ).
[Answer]
# If an operator is restricted from source, make a new one with `a`
Something that has come in handy for me a couple of times now is to avoid using a specific operator by pushing the ASCII value of the operator, using `a` to convert it to a string, and `s`toring this in a register to be executed as a macro later on. For example, I need to do division, but am either disallowed from or trying to avoid using the character `/`. I can, instead do `47asd` and then in the future when I need to divide 16 by 4, `16 4 ldx`.
* This will only work for single-character operators (can't build up a string), and will not work for commands like `s` that need to be postfixed by something.
* This adds quite a few bytes, and is therefore only suitable when avoiding the specific character is necessary or somehow affords a score bonus.
[Answer]
When initialising a ~~function~~ macro (we'll use `F`) that you want to run immediately, use something like `dsFx` rather than `sFlFx`. The same works for variables: `dsa` rather than `sala`.
If you need to do other stuff in between the storing and the loading (e.g., `sa[other stuff]la`), still consider whether the above is viable: If you leave a value on the stack before the other operations, will it be back at the top by the end of those operations?
[Answer]
Just discovered this by accident. Yet another way to generate a zero: `_`.
`_` is a signal to dc that the following digits are a negative number. Example:
```
_3 # pushes -3
```
But what if we don't follow it with a number?
```
_ # pushes 0...sometimes
```
This works when the next non-blank character following the underscore is not a digit. If a digit follows it, even after a newline, it is interpreted as a negative sign.
```
c4 5_6  # -6,5,4
c4 5_ 6 # -6,5,4
c4 5_
6       # -6,5,4 # still a negative sign since the next thing it sees is a digit
c4 5_z  #  3,0,5,4 # if it's followed by a non-digit, it's a 0
c4 5_p6 #  6,0,5,4
c4 _*   #  0 # 4*0=0
```
[Answer]
If the contents of the entire stack needs printing at the end of a program, a recursive macro loop could be used to achieve this. However, it is much shorter to simply use the `f` command.
[Answer]
`dc` reads input a line at a time. If you need to read in multiple items, doing it one-per line either requires a `?` for every line to be read, or a cumbersome macro loop. Instead, if all input items can be put on one space-separated line, then a single `?` will read all the input items, pushing each one onto the stack.
For example in `seq 10 | dc -e'?f'`, `seq` outputs integers 1-10, one per line. the `?` will just read the first `1` which will be output when `f` dumps the whole stack. However in `seq 10 | tr '\n' ' ' | dc -e'?f'`, the `tr` makes the input integers all space separated. In this case the `?` will read all the integers from the line in one go, and `f` will output them all.
[Answer]
# Avoiding whitespace
Avoiding whitespace comes up in quite a few challenges, and is generally easy in `dc`. Aside from strings, the one very specific time that whitespace becomes necessary is when pushing multiple numbers in a row: `1 2 3`. If this must be avoided:
* Execute an empty macro in between: `1[]x2[]x3[]x`.
* If brackets are off the table, store a NOP of a macro ahead of time: `35asn` and execute *it* in between: `1lnx2lnx3lnx`.
]