Un ejemplo rápido de lo que quiero usar bash scripting:
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
echo "scale=2; $float/1.18" |bc -l
read -p "Press any key to continue..."
bash scriptname.sh
Suponiendo que el precio es: 48.86 La respuesta será: 41.406779661 (41.40 en realidad porque estoy usando scale=2;
)
Mi pregunta es: ¿Cómo redondeo el segundo decimal para mostrar la respuesta de esta manera ?: 41.41
bc
no puede lograr lo que se solicita (o al menos la pregunta que estaba haciendo cuando encontré esta publicación), que es cómo redondear decimales usandobc
(eso se llama porbash
).r()
función, por lo que puede usarbc -le "r($float/1.18, 2)"
.Respuestas:
Una función bash round:
Usado en su ejemplo de código:
Buena suerte: o)
fuente
-0.5
$2 = 3
, tuve que usarecho $(env printf %.3f $(echo "scale=3;((1000*$1)+0.5)/1000" | bc))
. ¡Cuidado con el ambiente antes de printf! Esto te enseñará de nuevo que siempre es importante entender lo que estás copiando de otras partes.if [
echo "$ 1/1" | bc` -gt 0] `- ¿hay alguna forma más elegante de verificar (excepto analizar la cadena para" - ")?La solución más simple:
fuente
+0.5
. Intentaprintf "%.2f\n" "$(bc -l <<<"48.86/1.18")" "$(bc -l <<<"-48.86/1.18")"
y obtendrás41.41
y-41.41
.echo "$float/1.18" | bc -l | xargs printf %.2f
bash: printf: 1.69491525423728813559: invalid number
dependiendo de la configuración regional.Bash / awk redondeo:
Si tienes Python puedes usar algo como esto:
fuente
echo "$float" |awk '{printf "%.2f", $1/1.18}'
realizará la matemática solicitada de la pregunta a la precisión solicitada de centésimas. Eso es tanto "usar bash" como labc
llamada en la pregunta.python -c "print(round($num))"
dóndenum=4.678923
. No hay necesidad de fastidiar con stdin. También puede redonda de n dígitos, así:python -c "print(round($num, $n))"
.echo 5 | python -c "print int(round((float(raw_input())/2)-0.5))"
(Cuando + redondeará hacia arriba y - redondeará hacia abajo).Aquí hay una solución puramente bc. Reglas de redondeo: a +/- 0.5, redondeado desde cero.
Pon la escala que estás buscando en $ result_scale; sus matemáticas deben estar donde se encuentra $ MATH en la lista de comandos de bc:
fuente
MATH=-0.34;result_scale=1;bc <<MATH
, #ObjectiveAndClear: 5 como se explica aquí :)Sé que es una vieja pregunta, pero tengo una solución 'bc' pura sin 'if' o ramas:
Úselo como
bcr '2/3' 5
obcr '0.666666' 2
-> (expresión seguida de escala)Eso es posible porque en bc (como C / C ++) está permitido mezclar expresiones lógicas en sus cálculos. La expresión
((t>0)-(t<0))/2)
se evaluará a +/- 0.5 dependiendo del signo de 't' y, por lo tanto, usará el valor correcto para redondear.fuente
bcr "5 / 2" 0
regresa en2
lugar de3
. ¿Me estoy perdiendo de algo?En realidad es simple: no es necesario agregar explícitamente una variante "-0.5" codificada para números negativos. Hablando matemáticamente, simplemente calcularemos el valor absoluto del argumento y aún sumaremos 0.5 como lo haríamos normalmente. Pero dado que (desafortunadamente) no tenemos una
abs()
función incorporada a nuestra disposición (a menos que codifiquemos una), simplemente negaremos el argumento si es negativo.Además, resultó muy engorroso trabajar con el cociente como parámetro (ya que para mi solución, debo poder acceder al dividendo y al divisor por separado). Es por eso que mi script tiene un tercer parámetro adicional.
fuente
echo .. |
aritmética de concha, ¿de qué sirveecho $()
? Esto es fácil de explicar: ¡sus cadenas aquí siempre requerirán un directorio de escritura/tmp
! Y mi solución también funciona en un entorno de sólo lectura, por ejemplo, un intérprete de comandos de emergencia donde/
es que no siempre se puede escribir de forma predeterminada. Así que había una buena razón por la que lo codifiqué de esa manera.echo $()
alguna vez se necesita? Eso y la sangría provocaron mis ediciones, las herejías simplemente ocurrieron.echo $()
eso que se debió arreglar fue, de hecho, la penúltima línea, jajaja. Gracias por el aviso. Al menos este se ve mucho mejor ahora, no puedo negarlo. De todos modos, me encantó la lógica en esto. Un montón de cosas booleanas, menos "superfluos" (que seguramente explotarían el código en un 50 por ciento).Todavía estoy buscando una
bc
respuesta pura sobre cómo redondear solo un valor dentro de una función, pero aquí hay unabash
respuesta pura :Básicamente, esto extrae cuidadosamente los decimales, multiplica todo por 100 mil millones (10¹⁰,
10**10
inbash
), 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$int
y 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$int
y$fraction
luego ajusta eso para que coincida con la precisión (por ejemplo, seembiggen 48.86
convierte en 10¹⁰ × 4886/100 y devuelve488600000000
488,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
$answer
nos deja en cien veces la respuesta final.Ahora necesitamos agregar el punto decimal. Asignamos un nuevo
$int
valor a la$answer
exclusión de sus dos dígitos finales, luegoecho
con un punto y$answer
excluyendo el$int
valor 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
zsh
como mi shell es que admite matemáticas de punto flotante. La solución a esta pregunta es bastante sencilla enzsh
:(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).fuente
si tiene el resultado, por ejemplo considere 2.3747888
todo lo que tienes que hacer es:
esto redondea el número correctamente ejemplo:
los decimales se eliminan
bc
y se redondea a 2 como deberíafuente
Tuve que calcular la duración total de una colección de archivos de audio.
Entonces tuve que:
A. obtener la duración de cada archivo ( no se muestra )
B. sume todas las duraciones (cada una en
NNN.NNNNNN
segundos (fp))C. separar horas, minutos, segundos, segundos.
D. genera una cadena de HR: MIN: SEC: MARCOS, donde frame = 1/75 sec.
(Los marcos provienen del código SMPTE utilizado en los estudios).
A: usa
ffprobe
y analiza la línea de duración en un número fp (no se muestra)SI:
C:
RE:
fuente
Aquí hay una versión abreviada de su script, corregida para proporcionar la salida que desea:
Tenga en cuenta que redondear al entero más cercano es equivalente a sumar .5 y tomar el piso, o redondear hacia abajo (para números positivos).
Además, el factor de escala se aplica en el momento de la operación; entonces (estos son
bc
comandos, puedes pegarlos en tu terminal):fuente
Implementación pura de bc según lo solicitado
define ceil(x) { auto os,xx;x=-x;os=scale;scale=0 xx=x/1;if(xx>x).=xx-- scale=os;return(-xx) }
si coloca eso en un archivo llamado functions.bc, puede redondear con
echo 'ceil(3.1415)' | bc functions.bc
Código para la implementación de bc que se encuentra en http://phodd.net/gnu-bc/code/funcs.bc
fuente
fuente
Puede usar awk, no se necesitan tuberías:
Establezca el precio de antemano con la variable de entorno
PRICE=<val>
.Luego llame a awk:
$PRICE
entrará en awk como una variable awkprice
.Luego se redondea al centésimo más cercano con +.005.
La opción de formato printf
%.2f
limita la escala a dos decimales.Si tiene que hacer esto de esta manera, es mucho más eficiente que la respuesta seleccionada:
fuente