The following function compiles, but can only used with Doubles:
fun triang(x: Double): Double {
var m = x - truncate(x)
if (m < 0) m += 1.0
return when {
m < 0.25 -> 4.0 * m
m < 0.50 -> 2.0 - 4.0 * m
m < 0.75 -> 2.0 - 4.0 * m
else -> 4.0 * m - 4.0
}
}
I want to be able to use that function with Floats as well, so I tried making it into a generic function:
fun <T: Number> triang(x: T): T {
var m = x.toDouble() - truncate(x.toDouble())
if (m < 0) m += 1.0
return when {
m < 0.25 -> 4.0 * m
m < 0.50 -> 2.0 - 4.0 * m
m < 0.75 -> 2.0 - 4.0 * m
else -> 4.0 * m - 4.0
} as T // problem here
}
But this doesn't work, because the cast to T causes the warning, "Unchecked cast: Double to T".
How do I correctly write a generic function for both Float and Double?
Kotlin doesn't support casts for numbers like Java, and there is no definite way to convert a number to erased number type. It is much better to overload method for Double and Float.
However, you can suppress this warning, because actually this code will cast the return value to Number first, then it will call
<number type>Value
from it, but it is not very good, since this function is not designed for integer values and if you calltriang(1)
, it will cause precision loss in result.