list.1 丸めの例偶数丸めでも値が変化範囲が小さい場合など下位2桁が十分ランダムでは無い時には積算誤差が大きくなる場合があります。
入 力 四捨五入 偶数丸め i = 20 j = 20 k = 20 i = 19 j = 20 k = 20 i = 18 j = 20 k = 20 i = 17 j = 20 k = 20 i = 16 j = 20 k = 20 i = 15 j = 20 k = 20 i = 14 j = 10 k = 10 i = 13 j = 10 k = 10 i = 12 j = 10 k = 10 i = 11 j = 10 k = 10 i = 10 j = 10 k = 10 i = 9 j = 10 k = 10 i = 8 j = 10 k = 10 i = 7 j = 10 k = 10 i = 6 j = 10 k = 10 i = 5 j = 10 k = 0 i = 4 j = 0 k = 0 i = 3 j = 0 k = 0 i = 2 j = 0 k = 0 i = 1 j = 0 k = 0 i = 0 j = 0 k = 0 ------------------------- 計 210 220 210
return x / 10;
とすれば良いです。list.2 整数の偶数丸めのプログラム例 (C言語の場合)●補足
/* NAME * _rnd2evn - round least significant digit * SYNOPSIS * int rnd2evn(int x) * DISCRIPTIONS * The rnd2evn() function return the nearest multiple-of-ten value of x. * REFERENCE * ISO 31-0:1992, Quantities and units - Part0 : General principles, * Annex B (Guide to the rounding of numbers) * SEE ALSO * JIS Z 8401 * COPYRIGHT * Copyright (c) 2009, Takayuki HOSODA. All rights reserved. */ int rnd2evn(int x) { if (x > 0) { x += 4 + (1 & (x / 10)); }else{ x -= 4 + (1 & (x / 10)); } return x - (x % 10); }
list.3 正の整数の偶数丸めのプログラム例 (非推奨, C言語の場合)●補足2
int urnd2evn(int x) { x += 5; if (x % 20 == 10) x--; return x; }
list.4 実数の偶数丸めのプログラム例 (ISO C99 より前の C言語の場合)
#include <math.h> double round(double x) { double t; if (isnan(x)) return(x); if (isinf(x)) return(x); if (x >= 0.0) { t = floor(x); if (t - x <= -0.5) t += 1.0; return (t); } else { t = floor(-x); if (t + x <= -0.5) t += 1.0; return (-t); } }
list.5 2進数の2の冪での除算時の丸めの例入力を積算した場合の値 210 の半分の 105 に対して 偶数丸めの場合の積算値は 105 と誤差が少なく(この場合は零に)なっていますが、 単なる 1-bit 右シフトの積算値では 100 と 5% 少なくなっています。 これは、右シフトによる除算は単なる下位ビットの切り捨てと同じだから当然と言えます。
(シフトは 1-bit 右シフト。偶数丸めは list.6 (n = 1) による。)
入力 , シフト, 偶数丸め i = 20, j = 10, k = 10 i = 19, j = 9, k = 10 i = 18, j = 9, k = 9 i = 17, j = 8, k = 8 i = 16, j = 8, k = 8 i = 15, j = 7, k = 8 i = 14, j = 7, k = 7 i = 13, j = 6, k = 6 i = 12, j = 6, k = 6 i = 11, j = 5, k = 6 i = 10, j = 5, k = 5 i = 9, j = 4, k = 4 i = 8, j = 4, k = 4 i = 7, j = 3, k = 4 i = 6, j = 3, k = 3 i = 5, j = 2, k = 2 i = 4, j = 2, k = 2 i = 3, j = 1, k = 2 i = 2, j = 1, k = 1 i = 1, j = 0, k = 0 i = 0, j = 0, k = 0 ---------------------- 計 210, 100, 105
list.6 整数 x の n bit 右シフト時の偶数丸めのプログラム例 (n bit 右シフト, C言語の場合)[Dec. 1 2009] Rev.1.0
x = (x + ((1 << (n - 1)) - 1) + ((x >> n) & 1)) >> n;