Todavía estoy buscando una bcrespuesta pura sobre cómo redondear solo un valor dentro de una función, pero aquí hay una bashrespuesta pura :
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
embiggen() {
local int precision fraction=""
if [ "$1" != "${1#*.}" ]; then # there is a decimal point
fraction="${1#*.}" # just the digits after the dot
fi
int="${1%.*}" # the float as a truncated integer
precision="${#fraction}" # the number of fractional digits
echo $(( 10**10 * $int$fraction / 10**$precision ))
}
# round down if negative
if [ "$float" != "${float#-}" ]
then round="-5000000000"
else round="5000000000"
fi
# calculate rounded answer (sans decimal point)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))
int=${answer%??} # the answer as a truncated integer
echo $int.${answer#$int} # reassemble with correct precision
read -p "Press any key to continue..."
Básicamente, esto extrae cuidadosamente los decimales, multiplica todo por 100 mil millones (10¹⁰, 10**10in bash), ajusta la precisión y el redondeo, realiza la división real, divide de nuevo a la magnitud apropiada y luego reinserta el decimal.
Paso a paso:
La embiggen()función asigna la forma entera truncada de su argumento $inty guarda los números después del punto $fraction. El número de dígitos fraccionarios se indica en $precision. La matemática multiplica 10¹⁰ por la concatenación de $inty $fractionluego ajusta eso para que coincida con la precisión (por ejemplo, se embiggen 48.86convierte en 10¹⁰ × 4886/100 y devuelve 488600000000488,600,000,000).
Queremos una precisión final de centésimos, por lo que multiplicamos el primer número por 100, sumamos 5 para redondear y luego dividimos el segundo número. Esta asignación de $answernos deja en cien veces la respuesta final.
Ahora necesitamos agregar el punto decimal. Asignamos un nuevo $intvalor a la $answerexclusión de sus dos dígitos finales, luego echocon un punto y $answerexcluyendo el $intvalor que ya se ha solucionado. (No importa el error de resaltado de sintaxis que hace que esto parezca un comentario)
(Bashismo: la exponenciación no es POSIX, por lo que es un bashismo. Una solución POSIX pura requeriría bucles para agregar ceros en lugar de usar potencias de diez. Además, "embiggen" es una palabra perfectamente cromulante).
Una de las razones principales que uso zshcomo mi shell es que admite matemáticas de punto flotante. La solución a esta pregunta es bastante sencilla en zsh:
printf %.2f $((float/1.18))
(Me encantaría ver a alguien agregar un comentario a esta respuesta con el truco para habilitar la aritmética de punto flotante bash, pero estoy bastante seguro de que dicha característica aún no existe).