4

这可能是 1/2 数学,1/2 编程问题。但我们走了。

我有一个带有 2 位小数的随机小数。我将用一个随机整数来划分它。然后我想知道可能的最大舍入差异。

例子:

  decimal number = 100.00M;
  int x = 3;

  var result = number/x;
  var roundedResult = Round(result, 2, MidpointRoundingEx.AwayFromZero);
  // roundedResult = 33.33

  var roundingDiff = number - (roundedResult * x);
  // roundingDiff = 0.01

所以我这个例子的舍入差异是0.01。

但是“数字”可以是任何带有 2 位小数的数字,“x”可以是任何整数。所以我想知道是否可以提出一个公式,以便在任何情况下都能知道最大的舍入差异。

谢谢托马斯

4

2 回答 2

3

好的,你想要数学 - 让我们玩得开心!

假设 d 是带有两位小数的随机十进制数。

我们可以很容易地说

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,

所以最大差异将是最大 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

Why not exactly 0.5? Because in (*) we had implicit assumption that r can be x/2 for any x, which is not true, but hopefully it is enough for you purposes.

于 2013-03-23T12:09:21.060 回答
1

您可以使用这个单行公式计算差异:

var roundingDiff = ((int)(number * 100) % x - ((int)(number * 100) % x + x / 2) / x * x) / 100M;

对于给定x的,最大舍入差异是x / 200

于 2013-03-23T11:06:31.100 回答