しばしば必要となるのでメモ。
実施環境: Splunk Free 8.2.2
基本
Splunk で数値の端数処理を行いたい場合は、 eval コマンドの関数を用いると実現できます。
四捨五入の場合は round 、切り上げの場合は ceiling 、切り下げの場合は floor を使用します。
| makeresults
| eval NUM = 1.23
| eval NUM_R = round(NUM),
NUM_H = ceiling(NUM),
NUM_L = floor(NUM)
| makeresults
| eval NUM = 4.50
| eval NUM_R = round(NUM),
NUM_H = ceiling(NUM),
NUM_L = floor(NUM)
負の数の場合
ただし、数値が負の数の場合は少々注意が必要です。
まず、端数が.0から.4の場合は、
- 切り上げは「値が大きくなる方 = 0に近づく方」
- 切り下げは「値が小さくなる方 = 0から遠ざかる方」
- 四捨五入は「絶対値が小さくなる方 = 0に近づく方」
になります。
特に切り下げについては、「端数を無視する(切り捨て)」とは異なることに注意してください。
| makeresults
| eval NUM = -1.23
| eval NUM_R = round(NUM),
NUM_H = ceiling(NUM),
NUM_L = floor(NUM)
さらに面倒なのが端数が.5から.9の場合です。
切り上げ、切り下げは端数が.0から.4の時と同様です。
ですが、四捨五入については、
- 端数が**.5ちょうど**の場合は「絶対値が小さくなる方 = 0に近づく方」
- 端数が**.5よりごくわずかでも大きい**場合は「絶対値が大きくなる方 = 0から遠ざかる方」
と、正の数の時とは異なる挙動を見せます。
| makeresults
| eval NUM = -4.5
| eval NUM_R = round(NUM),
NUM_H = ceiling(NUM),
NUM_L = floor(NUM)
| makeresults
| eval NUM = -4.51
| eval NUM_R = round(NUM),
NUM_H = ceiling(NUM),
NUM_L = floor(NUM)
なお、このように.5以下の値は捨て、.5より大きい値は拾う端数処理の方法を五捨五超入と呼びます。
本頁では round 関数が行う処理を便宜上四捨五入と呼んでいますが、厳密にはこのように四捨五入とは異なる処理なのです。
切り捨て
Splunk において、「切り捨て」を行う関数は存在しません。
正の数であれば「切り捨て」は「切り下げ」と同じなので floor 関数を使用すれば問題ありませんが、負の数も考える場合は if 関数などを併用して上手く分岐を行う必要があります。
| makeresults count=5
| streamstats count AS NUM
| eval NUM = (NUM - 3) * 1.3
| eval NUM_T = if(NUM >= 0, floor(NUM), ceiling(NUM))
-0
負の数を切り上げた際、値が0になる場合は0ではなく「-0」という表記になります。
数値としては通常の0と同値として扱われますし、計算にも問題なく使用できます。
ただし、文字列として扱う場合は「0」と「-0」は異なる値として扱われるので注意してください。
| makeresults count=5
| streamstats count AS NUM
| eval NUM = (NUM - 3) * 0.4
| eval NUM_H = ceiling(NUM)
| eval NUM_H_CHK_I = if(NUM_H = 0, "ZERO", null()),
NUM_H_CHK_S = if(NUM_H = "0", "ZERO", null())
どうしても気になる場合は、0を足したりすれば0に揃います。
| makeresults count=5
| streamstats count AS NUM
| eval NUM = (NUM - 3) * 0.4
| eval NUM_H = ceiling(NUM)
| eval NUM_H_PLUS_0 = NUM_H + 0
なお、四捨五入においては「-0」は発生しません。
| makeresults count=5
| streamstats count AS NUM
| eval NUM = (NUM - 3) * 0.4
| eval NUM_R = round(NUM)
端数処理を行う桁
round 関数は第二引数で、四捨五入を行う桁を指定できます。
整数値にするなら0を指定し、小数点以下第1位までの値にするなら1を指定します。
では10単位の値にするなら-1なのかとなりますが、 round 関数の第二引数に負の数は指定できません。
| makeresults
| eval NUM = 12.39
| eval NUM_R0 = round(NUM, 0),
NUM_R1 = round(NUM, 1),
NUM_R-1 = round(NUM, -1)
10や100単位の値に四捨五入したい場合は、一旦10や100で割ったものを四捨五入し、再度10や100を掛けて桁数を戻すといった処理を行うことで実現できます。
また、整数以外に切り上げ、切り下げしたい場合も、 ceiling 関数や floor 関数は第二引数を指定できないため、同様の処理が必要です。
| makeresults
| eval NUM = 12.39
| eval NUM_R = round(NUM / 10) * 10,
NUM_H = ceiling(NUM / 10) * 10,
NUM_L = floor(NUM / 10) * 10