Kabuklardaki ilmeklerden kaçının.
Aritmetik yapmak istiyorsanız, awk
veya kullanın bc
:
awk '
BEGIN{
for (i = 4.00; i < 5.42; i+ = 0.02)
print i
}'
Veya
bc << EOF
for (i = 4.00; i < 5.42; i += 0.02) i
EOF
Not o awk
(aksine için bc
) sizin işlemciler ile çalışan double
nokta sayısı temsilini (olasılıkla kayan IEEE 754 tipi). Sonuç olarak, bu sayılar bu ondalık sayıların ikili yaklaşımları olduğundan, bazı sürprizleriniz olabilir:
$ gawk 'BEGIN{for (i=0; i<=0.3; i+=0.1) print i}'
0
0.1
0.2
Bir eklerseniz OFMT="%.17g"
eksiklerin nedenini görebilirsiniz 0.3
:
$ gawk 'BEGIN{OFMT="%.17g"; for (i=0; i<=0.5; i+=0.1) print i}'
0
0.10000000000000001
0.20000000000000001
0.30000000000000004
0.40000000000000002
0.5
bc
keyfi hassasiyette olduğundan, bu tür bir problem yaşamaz.
Varsayılan olarak (çıktı biçimini açık biçim belirtimleriyle değiştirmediyseniz OFMT
veya printf
açık biçim belirtimleriyle awk
kullanmıyorsanız ), %.6g
kayan nokta sayılarını görüntülemek için kullandığını , bu nedenle 1.000.000'un üzerindeki kayan nokta sayıları için 1e6 ve üstüne geçeceğini ve yüksek sayılar için kesirli kısmı keseceğini unutmayın (100000.02) 100000 olarak görüntülenir).
Eğer gerçekten mesela o döngünün her okunması için belirli komutları çalıştırmak istiyorum, çünkü, bir kabuk döngü kullanmak ya gibi nokta aritmetik desteği kayan bir kabuk kullanmak gerekiyorsa zsh
, yash
ya ksh93
yukarıdaki gibi tek bir komut ile değerler listesi veya oluşturmak (veya seq
varsa) ve çıktısı üzerinden döngü yapın.
Sevmek:
unset -v IFS # configure split+glob for default word splitting
for i in $(seq 4 0.02 5.42); do
something with "$i"
done
Veya:
seq 4 0.02 5.42 | while IFS= read i; do
something with "$i"
done
işlemcinizin kayan nokta sayılarının sınırlarını seq
zorlamazsanız, kayan nokta yaklaşımlarının neden olduğu hataları awk
yukarıdaki sürümden daha zarif bir şekilde işler .
Eğer yoksa seq
, (a GNU komut), gibi bir fonksiyonu olarak daha güvenilir bir tane yapabilirsiniz:
seq() { # args: first increment last
bc << EOF
for (i = $1; i <= $3; i += $2) i
EOF
}
Bu gibi şeyler için daha iyi çalışır seq 100000000001 0.000000001 100000000001.000000005
. Bununla birlikte, keyfi olarak yüksek hassasiyete sahip sayılara sahip olmanın, bunları desteklemeyen komutlara geçireceğimizde çok yardımcı olmayacağını unutmayın.