わかりました、あなたは数学が欲しいです-楽しみましょう!
dが小数点以下2桁の乱数であるとしましょう。
簡単に言うことができます
100d = n * x + r,
where 100d, n, x, r are integers, and 0 <= r < x
それで、
d / x = n / 100 + r / 100x
ここで、n / 100は丸めの観点から常に「良好」であるため、「r / x」の部分は、丸めに影響を与える唯一の部分であるため、興味深いものです。
0 <= r / x < 1,
0 <= r / 100x < 0.01
r / 100x> = 0.005の場合、丸められた結果に0.01が加算されます。これはr/x> = 1/2と同じで、r> = x/2と同じです。
わかりました。(d / x)の丸めはどちらかです
(1) n / 100, when r < x / 2, or
(2) n / 100 + 0.01, when r >= x / 2
四捨五入された違いは
diff = d - (n / 100) * x for (1), or
diff = d - (n / 100) * x + 0.01 * x for (2)
現在
(n / 100) * x = d - r/100
(2)の最大差は次のようになります。
max diff = r / 100 + 0.01 * x = (r + x) / 100
しかし、私たちが知っているように
x / 2 <= r < x,
したがって、最大diffは最大rになります:(*)
max diff = 2 * x * 0.01 = x / 200
ご覧のとおり、まだ特定のxに依存しているため、見積もりを行う必要があります。それが完全にランダムである場合-d自体までの任意の丸め差分を持つことができます。
たとえば、x <dとすると、max diff = d/200になります。
そしてプログラミング部分を追加するには:
decimal number = 100.00M;
decimal max = decimal.MinValue;
decimal min = decimal.MaxValue;
int maxX = 0;
int minX = 0;
for (int x = 1; x <= number; x++)
{
var result = number / x;
var roundedResult = Math.Round(result, 2, MidpointRounding.AwayFromZero);
var roundingDiff = number - (roundedResult * x);
if (roundingDiff < min)
{
min = roundingDiff;
minX = x;
}
if (roundingDiff > max)
{
max = roundingDiff;
maxX = x;
}
}
Console.WriteLine("Max is {0} for {1}", max, maxX);
Console.WriteLine("Min is {0} for {1}", min, minX);
Console.WriteLine("Delta is {0}", max - min);
Console.WriteLine("d / 200 = {0}", number / 200);
出力があります:
Max is 0.40 for 83
Min is -0.44 for 93
Delta is 0.84
d / 200 = 0.50
なぜ正確に0.5ではないのですか?(*)では、rは任意のxに対してx / 2である可能性があるという暗黙の仮定があったため、これは正しくありませんが、うまくいけば、目的には十分です。