3

我正在编写一个找到百分位数的程序。根据 eHow:

开始计算你的考试分数的百分位数(作为一个例子,我们将坚持你的分数 87)。使用的公式是 L/N(100) = P,其中 L 是分数低于 87 的测试数,N 是测试分数的总数(这里是 150),P 是百分位数。计算小于 87 的测试分数的总数。我们假设这个数字是 113。这给了我们 L = 113 和 N = 150。

因此,根据说明,我写道:

        string[] n = Interaction.InputBox("Enter the data set. The numbers do not have to  be sorted.").Split(',');
        List<Single> x = new List<Single> { };
        foreach (string i in n)
        {
            x.Add(Single.Parse(i));
        }
        x.Sort();
        List<double> lowerThan = new List<double> { };
        Single score = Single.Parse(Interaction.InputBox("Enter the number."));
        uint length = (uint)x.Count;
        foreach (Single index in x)
        {
            if (index > score)
            {
                lowerThan.Add(index);
            }
        }
        uint lowerThanCount = (uint)lowerThan.Count();

        double percentile = lowerThanCount / length * 100;
        MessageBox.Show("" + percentile);

然而程序总是返回 0 作为百分位数!我犯了什么错误?

4

5 回答 5

4

你的计算

double percentile = lowerThanCount / length * 100;

全部以整数完成,因为右侧由所有整数组成。至少一个操作数应该是浮点类型。所以

double percentile = (float) lowerThanCount / length * 100;
于 2013-11-05T14:36:46.057 回答
2

问题在于您用于变量的类型:在此表达式中

double percentile = lowerThanCount / length * 100;
//                  ^^^^^^^^^^^^^^^^^^^^^^^
//                           |  |  |
// This is integer division; since length > lowerThanCount, its result is zero

除法是对整数进行的,因此结果将为零。

将类型更改lowerThanCountdouble以解决此问题:

double lowerThanCount = (double)lowerThan.Count();
于 2013-11-05T14:36:40.393 回答
2

这实际上是一个舍入问题,因此lowerThanCount/length两者unit都不支持小数位,因此任何自然百分比计算(例如0.2/ 0.5)都会导致0.

例如,如果我们假设lowerThanCount = 10length = 20,总和看起来像

double result = (10 / 20) * 100

因此导致

(10 / 20) = 0.5 * 100

由于0.5不能表示为整数,因此浮点数被截断0,因此最终计算变为

0 * 100 = 0;

您可以通过强制计算使用浮点类型来解决此问题,例如

double percentile = (double)lowerThanCount / length * 100 

就可读性而言,在给定的计算中使用强制转换可能更有意义,并且lowerThanCount不会length自然地成为浮点数。


此外,您的代码可以使用 LINQ 简化很多

string[] n = Interaction.InputBox("Enter the data set. The numbers do not have to  be sorted.")
                        .Split(',');
IList<Single> x = n.Select(n => Single.Parse(n))
                   .OrderBy(x => x);
Single score = Single.Parse(Interaction.InputBox("Enter the number."));
IList<Single> lowerThan = x.Where(s => s < score);
Single percentile = (Single)lowerThan.Count / x.Count;
MessageBox.Show(percentile.ToString("%"));
于 2013-11-05T14:37:21.617 回答
1

您正在使用整数除法而不是浮点除法。在划分之前将length/lowerThanCount转换为浮点数。

于 2013-11-05T14:37:01.343 回答
1

除了百分位数计算(应该是浮点数),我认为你的计数在这里:

foreach (Single index in x)
    {
        if (index > score)
        {
            lowerThan.Add(index);
        }
    }

你检查索引,如果它们大于分数,你把它们放入lowerThan 只是一个逻辑错误?

编辑:对于百分位数问题,这是我的解决方法:

 double percentile = ((double)lowerThanCount / (double)length) * 100.0;

你可能不需要所有的(双),但为了安全起见......

于 2013-11-05T14:45:56.953 回答