I have been trying to create a small method to calculate given percentile from a seq. It works.. almost. Problem is I don't know why is doesn't work. I was hoping one of your 'a bit smarter' people than me could help me with it.
What I hope the result would be is that it would return the item from the seq that n prosent of the seq is smaller than equal than returned value.
def percentile[Int](p: Int)(seq: Seq[Int]) = {
require(0 <= p && p <= 100) // some value requirements
require(!seq.isEmpty) // more value requirements
val sorted = seq.sorted
val k = math.ceil((seq.length - 1) * (p / 100)).toInt
return sorted(k)
}
So for example if I have
val v = Vector(7, 34, 39, 18, 16, 17, 21, 36, 17, 2, 4, 39, 4, 19, 2, 12, 35, 13, 40, 37)
and I call my function percentile(11)(v)
return value is 2. However, 10% of the vector are smaller or equal than 2, not 11% like I am calling. percentile(11)(v)
should return 4.
your error is in this row:
val k = math.ceil((seq.length - 1) * (p / 100)).toInt
and particularly here: p / 100
. Being p
an Int <= 100 and >= 0, p/100
will always be equal to 0 or 1 (if p == 100
). If you want a floating point result, you have to widen one of the two values to double: p/100.0
val k = math.ceil((seq.length - 1) * (p / 100.0)).toInt
On a side note: you don't need the [Int]
type parameter
The problem is with the part p / 100
in
val k = math.ceil((seq.length - 1) * (p / 100)).toInt
Since p
is of type Int
and 100
is also an Int
, the division is an integer division that returns an Int
. If either p
or 100
is a Double
, the result will be a Double
.
The easiest fix would be to change that part in p / 100.0
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With