public long GetValueAtPercentile(double percentile)
{
var requestedPercentile = Math.Min(percentile, 100.0); // Truncate down to 100%
var countAtPercentile = (long)(((requestedPercentile / 100.0) * TotalCount) + 0.5); // round to nearest
countAtPercentile = Math.Max(countAtPercentile, 1); // Make sure we at least reach the first recorded entry
long runningCount = 0;
for (var i = 0; i < BucketCount; i++)
{
var j = (i == 0) ? 0 : (SubBucketCount / 2);
for (; j < SubBucketCount; j++)
{
runningCount += GetCountAt(i, j);
if (runningCount >= countAtPercentile)
{
var valueAtIndex = ValueFromIndex(i, j);
return this.HighestEquivalentValue(valueAtIndex);
}
}
}
throw new ArgumentOutOfRangeException(nameof(percentile), "percentile value not found in range"); // should not reach here.
}