Skip to main content
1 of 9
Toby Speight
  • 9.4k
  • 3
  • 32
  • 54

This answer to the first linked question has the almost-throwaway line at the end:

See also %g for rounding to a specified number of significant digits.

So you can simply write

printf "%.2g" $n

Examples:

$ printf "%.2g\n" 76543 0.0076543
7.7e+04
0.0077

Of course, you now have mantissa-exponent representation rather than pure decimal, so you'll want to convert back:

$ printf "%0.f\n" 7.7e+06
7700000

$ printf "%0.7f\n" 7.7e-06
0.0000077

Putting all this together, and wrapping it in a function:

#!/bin/bash

# Function round(precision, number)
round() {
    n=$(printf "%.${1}g" "$2")
    if [ "$n" != "${n#*e}" ]
    then
        f="${n##*e-}"
        test "$n" = "$f" && f= || f=$[ $f+$p+1 ]
        n=$(printf "%0.${f}f" "$n")
    fi
    printf "%s" "$n"
}

Test cases

for i in $(seq 6 -1 1)
do
    #echo $(dc <<<"15k 1.234 10 $i ^/p")
    echo $(round 3 $(dc <<<"15k 1.234 10 $i ^/p"))
done
for i in $(seq 0 6)
do
    #echo $(dc <<<"1.234 10 $i ^*p")
    echo $(round 3 $(dc <<<"1.234 10 $i ^*p"))
done

Test results

0.0000012
0.000012
0.00012
0.0012
0.012
0.12
1.2
12
120
1200
12000
120000
1200000
Toby Speight
  • 9.4k
  • 3
  • 32
  • 54