Converte o índice de loop do bash em ponto flutuante

0

Eu preciso usar o índice i em um loop como for i in {0..10..5} em um cálculo de ponto flutuante. Qual é a maneira mais simples de converter i em ponto flutuante?
Variações sobre

i=$(bc -l <<< "scale=7;$i")

não funciona.

    
por user94858 29.05.2016 / 10:50

2 respostas

5

Use bc ou awk ou um shell com suporte a ponto flutuante como ksh93 , zsh ou yash em vez de bash .

bc

$ bc -l << \EOF
heredoc> for (i = 0; i <=  10; i += 2.5) i / 2
heredoc> EOF
0
1.25000000000000000000
2.50000000000000000000
3.75000000000000000000
5.00000000000000000000

awk

$ awk 'BEGIN {for (i = 0; i <= 10; i += 2.5) print i / 2}'
0
1.25
2.5
3.75
5

zsh

$ float i; for ((i = 0; i <= 10; i += 2.5)) print $((i/2))
0.
1.25
2.5
3.75
5.

ksh93

$ for ((i = 0; i <= 10; i += 2.5)); do print "$((i/2))"; done
0
1.25
2
3.75
5

(cuidado com o separador decimal é dependente de localidade ( . ou , ).

yash

i=0; while [ "$((i <= 10))" -ne 0 ]; do
  echo "$((i / 2))"
  i=$((i + 2.5))
done

(dentro de $((...)) você usa . como o separador decimal, mas na E / S, o código do código do idioma ( . ou , ) é usado).

Editar

agora, se você quiser apenas fazer um loop em alguns inteiros e esses números inteiros serem representados com um ponto decimal neles, basta acrescentar um .0 :

 for i in {0..10..5}.0

Ou, para as soluções acima, use printf "%.7f\n" em vez de print / echo para gerar os números com 7 dígitos após o separador decimal.

    
por 29.05.2016 / 11:19
1

Você precisa dividir o valor por algo (até 1) em bc para que a escala importe:

$ i=5; bc -l <<< "scale=7;$i/1"
5.0000000

$  i=5; bc -l <<< "scale=7;$i/2"
2.5000000

Editar:

Para o caso especial 0 (que não adiciona .0000000 por padrão), você pode adicionar:

$ [ "$i" -eq 0 ] && i="0.0000000"

Mas cuidado para que isso não torne o valor um número de ponto flutuante, apenas uma string parecida com um número de ponto flutuante.

Além disso, você poderia printf a representação necessária:

$ i=3.75
$ i=$( printf "%.7f\n" "$i" )
$ echo "$i"
3.7500000

Tenha em conta que o bash printf honrará o separador decimal local. Se for uma vírgula, você deve escrever i=3,75 e você receberá o resultado também com uma vírgula.

Você precisará mudar para algum outro idioma ou alguns shells para realmente usar números de ponto flutuante:

Use um ponto para o decimal.

$ awk 'BEGIN { i=5; print( i / 2 ); i=7; print( i / 3 ) }'
2.5
2.33333

Respeite as configurações do local.

$ float i; i=7; print $((i/2)); print $((i/3)); print $((3,7/2))
3,5
2,33333333333333333
1,85

O zsh usará um ponto . , mesmo em locais que use uma vírgula , .

$ float i; i=7; print $((i/2)); print $((i/3))         ### or typeset -f i
3.5
2.3333333333333335

$ echo $(( 7/3 )); echo $(( 7.0/3 ))
2
2,33333333333333

$ i=7; echo $(( i/3 )); i=7,0; echo $(( i/3 ))
2
2,33333333333333

Os números flutuantes devem ser atribuídos com o separador decimal de localidade.
No entanto, dentro de $(( )) um ponto deve ser usado.

    
por 30.05.2016 / 05:59