Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Percentile algorithm

Tags:

c#

I am writing a program that finds percentile. According to eHow:

Start to calculate the percentile of your test score (as an example we’ll stick with your score of 87). The formula to use is L/N(100) = P where L is the number of tests with scores less than 87, N is the total number of test scores (here 150) and P is the percentile. Count up the total number of test scores that are less than 87. We’ll assume the number is 113. This gives us L = 113 and N = 150.

And so, according to the instructions, I wrote:

        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);

Yet the program always returns 0 as the percentile! What errors have I made?

like image 786
Edward Karak Avatar asked Mar 23 '26 21:03

Edward Karak


2 Answers

Your calculation

double percentile = lowerThanCount / length * 100;

is all done in integers, since the right hand side consist of all integers. Atleast one of the operand should be of floating point type. So

double percentile = (float) lowerThanCount / length * 100;
like image 106
Habib Avatar answered Mar 25 '26 09:03

Habib


This is effectively a rounding problem, lowerThanCount / length are both unit therefore don't support decimal places so any natural percentage calculation (e.g. 0.2/0.5) would result in 0.

For example, If we were to assume lowerThanCount = 10 and length = 20, the sum would look something like

double result = (10 / 20) * 100

Therefore results in

(10 / 20) = 0.5 * 100

As 0.5 cannot be represented as an integer the floating point is truncated which leaves you with 0, so the final calculation eventually becomes

0 * 100 = 0;

You can fix this by forcing the calculation to work with a floating point type instead e.g.

double percentile = (double)lowerThanCount / length * 100 

In terms of readability, it probably makes better sense to go with the cast in the calculation given lowerThanCount & length won't ever naturally be floating point numbers.


Also, your code could be simplified a lot using 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("%"));
like image 26
James Avatar answered Mar 25 '26 10:03

James



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!