Is it possible to round the top of the stack using dc in a shell skript? If yes are there commands to round the result up and down?
Thanks guys!
The dc
manual says:
Most arithmetic operations are affected by the "precision value", which you can set with the
k
command. The default precision value is zero ...
/
Pops two values, divides the second one popped from the first one popped, and pushes the result. The number of fraction digits is specified by the precision value.
So you can truncate (round toward zero) using 0k1/
, or just 1/
if you know that the precision is 0, which it is by default. For example:
$ dc -e '12.9 1/ p'
12
$ dc -e '_12.9 1/ p'
-12
Other kinds of rounding are more difficult. To round to the nearest integer, you can use [_1*]sad.5r0>a+0k1/
, for example:
$ dc -e '12.9 [_1*]sad.5r0>a+0k1/ p'
13
$ dc -e '_12.9 [_1*]sad.5r0>a+0k1/ p'
-13
A quick explanation:
[_1*]sa
stores the command _1*
(multiply by −1) in register a
.d
duplicates the value on top of the stack (the value we want to round, call it v)..5r
pushes 0.5 and then swaps the top two values, so the stack is now v 0.5 v.0>a
executes the command in register a
if 0 > v (that is, if v is negative). The stack is now 0.5 v if v is positive, or −0.5 v if v is negative.+
adds the top two values and pushes v + 0.5 if v is positive, or v − 0.5 if v is negative.0k1/
truncates as described above.If you know that the number you are rounding is non-negative, you can just use .5+0k1/
; and if you additionally know the precision is 0 you can use .5+1/
.
To round down, use [dX[1-]sa0<a]sad0>a0k1/
.
To round up, use [dX[1+]sa0<a]sad0<a0k1/
.
All these suggestions use the register a
, so you might need to adjust them in your actual program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With