traduccion script done bash floating-point math expression

script - Expresiones aritméticas de BASH



cat<< linux (5)

Había usado varias formas de hacer aritmética entera de enteros en BASH (3.2). Pero no puedo encontrar la mejor manera (preferida) de hacerlo.

result=`expr 1 + 2` result=$(( 1 + 2 )) let "result = 1 + 2"

¿Cuáles son las diferencias fundamentales entre esas expresiones?
¿Hay otras formas de hacer lo mismo?

¿Es obligatorio el uso de una herramienta como bc para la aritmética de punto flotante?

result=`echo "7/354" | bc`


En Bash, let permitir múltiples asignaciones en una línea:

let a=3 b=4 c=5

Como se muestra en su pregunta, la cita del argumento para let colocar espacios alrededor de los operadores. Sin embargo, puede omitir las comillas si evita usar espacios.

Otra forma que usa paréntesis dobles al comienzo de la declaración (en lugar de la forma i=$((j + 1)) ) le permite incluir espacios alrededor del signo igual o realizar operaciones de post incrementos o reducciones previas o posteriores y adicionales. :

(( a = ( b + c ) * 4 )) (( count++ )) (( d = --c**2 )) (( e *= 2 )) (( f = 3, g = 5 )) # multiple operations require a comma separator

Si usted help "((" dice que el doble paréntesis es ''Equivalente a " let EXPRESSION ".''

Puede utilizar la función incorporada declare para realizar asignaciones, incluidas indirectamente:

blue=2 name=blue declare $name=4 echo $blue # result: 4 echo ${!name} # result: 4

Editar:

La construcción $(()) se llama " expansión aritmética " y hace que los contenidos se evalúen como una expresión entera. Es un elemento de sintaxis del shell.

Si una variable se declara como un número entero, no necesita utilizar ninguna forma de paréntesis dobles, puede omitir el signo de dólar del nombre de la variable (como en las formas de paréntesis dobles), pero no puede agregar espacios alrededor de los operadores :

declare -i x=1 # set integer, initialize to 1 declare +i s=1 # clear integer, initialize to 1 x+=1 # could also be x=x+1 echo $x # result: 2 (addition) s+=1 # could also be s=$s+1, requires a "$" echo $s # result: 11 (string concatenation)

A diferencia de los formularios anteriores, llamar a expr implica generar un ejecutable externo que puede ser bastante caro para muchos cálculos en un bucle. La única vez que se debe usar es en entornos donde el shell no puede hacer su propia aritmética o para portabilidad cuando un script puede encontrar su camino en dicho entorno. Las carcasas POSIX tienen capacidad aritmética, por lo que sería una preocupación solo para sistemas más antiguos.

Con respecto al uso de bc para la aritmética de punto flotante, se requiere esto o algo similar cuando se usa Bash y muchos otros shells. POSIX dice que "Sólo se requiere aritmética de enteros largos firmados".

Dos shells que soportan matemática flotante son ksh y zsh. Además de bc , puede usar dc , AWK, Python, Perl y otros desde un script Bash.

Una cosa que Bash hará con los números de punto flotante es imprimirlos con el printf integrado (tenga en cuenta que también hay un printf externo, pero los incorporados tienen prioridad).

printf "%''14.4f/n" 1234.56 # result " 1,234.5600" (in my locale)


La tercera opción que tienes es mucho menos legible ya que no parece un operador de asignación. El primero, como han señalado otros, llama un comando externo


No puedo decir que sea "obligatorio" pero bc es probablemente tu mejor apuesta para la aritmética de propósito general.

Para algo más sofisticado, siempre puedes pasar por Perl.

La desventaja de ambos enfoques es que ambos abren un proceso secundario, por lo que hacerlo en un circuito cerrado será más lento que las expresiones nativas de bash (el mismo problema surge con el uso de backticks, en su primer ejemplo). No estoy seguro de si $(()) llama a un proceso hijo.


Prefiero tu segunda opción, ya que no necesita una utilidad externa:

result=$(( 1 + 2 ))

La primera opción llama a expr a hacer los cálculos, no estoy familiarizado con let . Otra alternativa a bc es dc . Elige tu favorito.


Is the use of a tool like bc mandatory for floating point arithmetic?

No, si está utilizando un shell que admite punto flotante, por ejemplo, zsh, ksh. De lo contrario, si desea realizar cálculos matemáticos de punto flotante más avanzados, utilice uno de estos, bc/awk/dc . Por supuesto, también Perl / Python, etc.