切り下げ、切り上げ、四捨五入
floor 小数部の切り下げ - Perl入門〜サンプルコードによるPerl入門〜に Perl を用いた例が載っていますが、awk には切り下げ (floor)、切り上げ (ceil)、四捨五入 (round) という関数が用意されていません。 これらを awk で実装することは比較的簡単ですので、実装しています。
#! /usr/bin/gawk -f
# floor.awk
BEGIN {
print "num : floor: ceil : round";
for (i = -20; i <= 20; i++) {
j = i / 10;
printf("%5.2f: %5d: %5d: %5d\n", j, floor(j), ceil(j), round(j));
}
}
# 小数部の切り下げ
# in: 数値 num
# out: 数値 num の小数部を切り下げたもの
function floor(num) {
if (int(num) == num) {
return num;
} else if (num > 0){
return int(num);
} else {
return int(num) - 1;
}
}
# 小数部の切り上げ
# in: 数値 num
# out: 数値 num の小数部を切り上げたもの
function ceil(num) {
if (int(num) == num) {
return num;
} else if (num > 0) {
return int(num) + 1;
} else {
return num;
}
}
# 小数部の四捨五入
# in: 数値 num
# out: 数値 num の小数部を四捨五入したもの
function round(num) {
if (num > 0) {
return int(num + 0.5);
} else {
return int(num - 0.5);
}
}
これらの関数は慣用句のようになっていますので、どうしてそのような実装になるのかを考えてみてください。
$ nawk -f floor.awk num : floor: ceil : round -2.00: -2: -2: -2 -1.90: -2: -1: -2 -1.80: -2: -1: -2 -1.70: -2: -1: -2 -1.60: -2: -1: -2 -1.50: -2: -1: -2 -1.40: -2: -1: -1 -1.30: -2: -1: -1 -1.20: -2: -1: -1 -1.10: -2: -1: -1 -1.00: -1: -1: -1 -0.90: -1: 0: -1 -0.80: -1: 0: -1 -0.70: -1: 0: -1 -0.60: -1: 0: -1 -0.50: -1: 0: -1 -0.40: -1: 0: 0 -0.30: -1: 0: 0 -0.20: -1: 0: 0 -0.10: -1: 0: 0 0.00: 0: 0: 0 0.10: 0: 1: 0 0.20: 0: 1: 0 0.30: 0: 1: 0 0.40: 0: 1: 0 0.50: 0: 1: 1 0.60: 0: 1: 1 0.70: 0: 1: 1 0.80: 0: 1: 1 0.90: 0: 1: 1 1.00: 1: 1: 1 1.10: 1: 2: 1 1.20: 1: 2: 1 1.30: 1: 2: 1 1.40: 1: 2: 1 1.50: 1: 2: 2 1.60: 1: 2: 2 1.70: 1: 2: 2 1.80: 1: 2: 2 1.90: 1: 2: 2 2.00: 2: 2: 2
上記コードの for 文は小数点を用いないように、あらかじめ 10 倍していますが、このあたりもどうして 10 倍しているのかを含めて考えてみてください。 10 倍しない場合には以下のようになります。
#! /usr/bin/gawk -f
# floor_2.awk
BEGIN {
print "num : floor: ceil : round";
for (j = -2; j <= 2; j = j + 0.1) {
printf("%5.2f: %5d: %5d: %5d\n", j, floor(j), ceil(j), round(j));
}
}
# 小数部の切り下げ
# in: 数値 num
# out: 数値 num の小数部を切り下げたもの
function floor(num) {
if (int(num) == num) {
return num;
} else if (num > 0){
return int(num);
} else {
return int(num) - 1;
}
}
# 小数部の切り上げ
# in: 数値 num
# out: 数値 num の小数部を切り上げたもの
function ceil(num) {
if (int(num) == num) {
return num;
} else if (num > 0) {
return int(num) + 1;
} else {
return num;
}
}
# 小数部の四捨五入
# in: 数値 num
# out: 数値 num の小数部を四捨五入したもの
function round(num) {
if (num > 0) {
return int(num + 0.5);
} else {
return int(num - 0.5);
}
}
実行してみましょう。
$ nawk -f floor_2.awk num : floor: ceil : round -2.00: -2: -2: -2 -1.90: -2: -1: -2 -1.80: -2: -1: -2 -1.70: -2: -1: -2 -1.60: -2: -1: -2 -1.50: -2: -1: -1 -1.40: -2: -1: -1 -1.30: -2: -1: -1 -1.20: -2: -1: -1 -1.10: -2: -1: -1 -1.00: -1: 0: -1 -0.90: -1: 0: -1 -0.80: -1: 0: -1 -0.70: -1: 0: -1 -0.60: -1: 0: -1 -0.50: -1: 0: 0 -0.40: -1: 0: 0 -0.30: -1: 0: 0 -0.20: -1: 0: 0 -0.10: -1: 0: 0 0.00: 0: 1: 0 <- ここの挙動がおかしい 0.10: 0: 1: 0 0.20: 0: 1: 0 0.30: 0: 1: 0 0.40: 0: 1: 0 0.50: 0: 1: 1 0.60: 0: 1: 1 0.70: 0: 1: 1 0.80: 0: 1: 1 0.90: 0: 1: 1 1.00: 1: 2: 1 1.10: 1: 2: 1 1.20: 1: 2: 1 1.30: 1: 2: 1 1.40: 1: 2: 1 1.50: 1: 2: 2 1.60: 1: 2: 2 1.70: 1: 2: 2 1.80: 1: 2: 2 1.90: 1: 2: 2




