exupero's blog

# Stack-math compendium

To wrap-up this series on stack-based mental math algorithms, below are approximations for three dozen conversions. If you find a better algorithm for any of those listed, or you'd like to suggest additional conversions, please email me.

(For the implementation of the `times` operation, see the end of the post.)

ConversionEstimateError
Celsius → Fahrenheit`[9 * 5 / 32 +]``[double subtract-tenth 32 +]`0.0%
Fahrenheit → Celsius`[32 - 5 * 9 /]``[32 - halve add-tenth]`1.0%
15% tip`[0.15 *]``[add-half tenth]`0.0%
multiply by π`[3.1416 *]``[triple dup halve tenth +]`0.3%
divide by π`[3.1416 /]``[third dup halve tenth -]`0.5%
kilometers → miles`[0.6214 *]``[dup [triple] dip tenth + double tenth]`0.2%
miles → kilometers`[1.609 *]``[dup [add-half] dip tenth +]`0.6%
meters → feet`[3.281 *]``[triple add-tenth]`0.6%
feet → meters`[0.3048 *]``[third subtract-tenth]`1.6%
miles → feet`[5280 *]``[dup tenth halve + halve 10000 *]`0.6%
feet → miles`[5280 /]``[dup tenth halve - double 10000 /]`0.3%
kilograms → pounds`[2.205 *]``[double add-tenth]`0.2%
pounds → kilograms`[2.205 /]``[halve subtract-tenth]`0.8%
hours → seconds`[3600 *]``[double double subtract-tenth 1000 *]`0.0%
seconds → hours`[3600 /]``[halve halve add-tenth 1000 /]`1.0%
meters per second → miles per hour`[2.237 *]``[double add-tenth]`1.7%
miles per hour → meters per second`[0.447 *]``[halve subtract-tenth]`0.7%
miles per hour → feet per second`[1.467 *]``[add-half]`2.2%
feet per second → miles per hour`[0.6818 *]``[third double]`2.2%
square miles → acres`[640 *]``[7 * subtract-tenth 100 *]`1.6%
acres → square miles`[640 /]``[7 / add-tenth 100 /]`0.6%
acres → square feet`[43560 *]``[double double add-tenth 10000 *]`1.0%
square feet → acres`[43560 /]``[halve halve subtract-tenth 10000 /]`2.0%
square kilometers → acres`[247.1 *]``[halve halve 1000 *]`1.2%
pounds → troy ounces`[14.58 *]``[dup [add-half tenfold] dip halve -]`0.5%
troy ounces → pounds`[14.58 /]``[third double tenth]`2.8%
US cups → fluid ounces`[8 *]``[[double] 3 times]`0.0%
fluid ounces → US cups`[8 /]``[[halve] 3 times]`0.0%
liquid gallons → US cups`[16 *]``[[double] 4 times]`0.0%
US cups → liquid gallons`[16 /]``[[halve] 4 times]`0.0%
liquid gallons → liters`[3.785 *]``[dup tenth halve - double double]`0.4%
liters → liquid gallons`[3.785 /]``[dup tenth halve + halve halve]`0.6%
sphere radius → surface area`[dup * 3.1416 * 4 *]``[dup * tenfold dup halve halve +]`0.5%
sphere radius → volume`[dup dup * * 3.1416 * 4 * 3 /]``[dup dup * * double double dup halve tenth +]`0.3%
sphere surface area → radius`[4 / 3.1416 / sqrt]``[[double] 3 times tenth tenth sqrt]`0.3%
sphere volume → radius`[3 * 4 / 3.1416 / cube-root]``[halve halve cube-root]`1.5%

For the conversion of sphere surface area and volume to radius, accuracy naturally depends on your choice of algorithm for `sqrt` and `cube-root`. The error percentages listed above use high-precision accuracy, but for practical mental math uses, these algorithms should be good enough.

Here's the implementation of the `times` operation:

``````(def times
^:stack-op
(fn [stack]
(let [n (peek stack)
ops (peek (pop stack))
stack (pop (pop stack))]
(nth (iterate #(execute % ops) stack) n))))``````