![常規關係運算子 '](https://rvso.com/image/169423/%E5%B8%B8%E8%A6%8F%E9%97%9C%E4%BF%82%E9%81%8B%E7%AE%97%E5%AD%90%20'.png)
我有一個這樣的文件:
0.2
0.2
0.2
0.2
0.2
0.2
0.2024
0.2025
0.2027
0.2027
0.2029
0.2059
0.2059
0.2059
0.2059
0.2099
0.2099
0.2099
0.2105
0.2113
0.2113
0.2195
0.2198
0.2206
0.2206
0.2206
0.2989
0.2989
0.2989
0.3
0.3
我想計算一個範圍內包含的值的數量,例如:
0.2 18
0.21 5
0.22 3
0.23 0
0.24 0
0.25 0
0.26 0
0.27 0
0.28 0
0.29 3
0.3 2
如您所見,我使用的間隔為 0.01。我正在用來awk
實現它,但我遇到了一些奇怪的行為:
awk 'BEGIN {for (i=0;i<1.01;i+=0.01) a[i]=0} {
for (j=0;j<=1;j+=0.01)
if($1>=j && $1<j+0.01) {
a[j]+=1
}
}
END {for (k=0;k<1.01;k+=0.01) print k,a[k]}' test_OH.txt
結果:
0.19 6
0.2 12
0.21 5
0.22 3
0.23 0
0.24 0
0.25 0
0.26 0
0.27 0
0.28 0
0.29 5
0.3 0
有人可以幫我嗎?我猜想<
它沒有按預期工作,因為它滿足 when $1 == j+0.01
.當然,我沒有考慮什麼。謝謝你!
答案1
awk -v s=0.2 -v e=0.3 -v d=0.01 '
BEGIN { m = 1/d }
{ a[int($1*m)]++ }
END{ e *= m; for(s = int(s*m); s <= e; s++) print s*d, a[s]+0 }
' test_OH.txt
0.2 18
0.21 5
0.22 3
0.23 0
0.24 0
0.25 0
0.26 0
0.27 0
0.28 0
0.29 3
0.3 2
(開始s
)e
(結束)和d
(增量/步長)變數可以根據需要進行調整。
透過重複相加產生一個範圍
0.01
幾乎是教科書上關於浮點數不能做什麼的例子,因為浮點數0.01
不能精確地用基數 2 表示,而且每次相加誤差都會累積。掃描每條線的整個範圍是低效且毫無意義的。
awk 中的變數不必初始化為
""
or0
。
答案2
試試這個:
awk '
BEGIN {for (i=0;i<1.01;i+=0.01) a[i]=0}
{
n = int($1 * 100) / 100
a[n] += 1
}
END {for (k=0;k<1.01;k+=0.01) print k,a[k]}'
或者這個,我覺得不太容易理解:
awk 'BEGIN {for (i=0;i<1.01;i+=0.01) a[i]=0} {
for (j=0;j<=1;j+=0.01)
if(("X" $1 >= "X" j) && ("X" $1 < "X" j+0.01)) {
a[j]+=1
}
}
END {for (k=0;k<1.01;k+=0.01) print k,a[k]}'
至於原版不起作用的原因,請參見上面卡西莫多的評論。
答案3
不確定我是否應該將其作為答案或評論發布,但這裡有一個簡短的演示,說明了我的機器上這種情況下的不準確性和結果數字:
$ awk 'BEGIN { d = 0.01; printf "%.20f\n", d; for (i = 0; i < 30; i++) a += d; printf "%.20f\n%.20f\n", 0.3, a }'
0.01000000000000000021
0.29999999999999998890
0.30000000000000009992
第一個數字是 0.01 實際儲存的數字,它不準確,因為 1/100 包含一個因子 1/5 並且不能用二進位表示。
第二個是 0.3 儲存的內容,第三個是 0.01 加上自身 30 次。 (我想,這甚至不一樣,0.01 * 30
因為每一步都有中間捨去。)
其他答案都有解決方案,按讚吧。