Dividing two Int’s returns another Int. This behavior is the same as in Java and I find it to be very dangerous and un-intuitive.
For example: The expression 5/2 evaluates to 2 instead of the correct value of 2.5
To get the correct value, the user must first parse one of the Int’s to Double like this:
5/2.toDouble()
This behavior of silent rounding is almost never wanted and can be quite hard to debug since 5/2 is mathematically correct.
I propose a change of Int.div(Int):Int to Int.div(Int):Double
Although this might some existing code due to Incompatibility of Double and Int, I think it will prevent enough bugs in the future to make it worth it.
Mathematically speaking the current behaviour is correct. This is called integer devision and results in the quotient as an answer. For more information see: Division (mathematics) - Wikipedia
But I suspect you have a background in a language like Javascript, which only has one numeric type, and expect the same behaviour here. Your statement that this behaviour is “almost never wanted” is just your own perspective. In general sense it will not hold.
In addition, mainstream compiled languages all have the same behaviour as Kotlin. Not only that, there is a special CPU instruction for it that is much faster than floating point division. To have the suggested behaviour would be very surprising for many users of the language, and would under water involve a conversion of both parameters to doubles (note that float cannot represent the full range of integer values). In the case of long numbers you could even get an incorrect answer due to doubles not capturing the full precision of 64 bit integers.
This is very unlikely to be changed for compatibility reasons
From a backwards compatibility standpoint and a Java similarity standpoint, it would be wrong to change the behaviour of the division operator like this.
You can do this with an infix extension function instead.
infix fun Int.fdiv(i: Int): Double = this / i.toDouble();
Then you could do this kind of division like this:
1 fdiv 2
If a new operator would be introduced for this, it could be perhaps be /.
or ./
The precision yielded by this operator (single or double) would have to be inferred somehow, or specified with a prefix or suffix.
It might look out of place and would cause confusion whether or not one should use the ordinary division operator when both operands are not ints.
There is a whole Python PEP discussing this PEP 238 – Changing the Division Operator. It would be awesome if Kotlin’s designers have chosen the Python way to “floor division”. I’m sorry for reviving this, learning Kotlin in 2021 and it was awkward for me when my math results was not what I expected (=
It seems the PEP already addresses this for Kotlin (well, for statically typed languages) under the “Motivation” section:
The problem is unique to dynamically typed languages: in a statically typed language like C, the inputs, typically function arguments, would be declared as double or float, and when a call passes an integer argument, it is converted to double or float at the time of the call. Python doesn’t have argument type declarations, so integer arguments can easily find their way into an expression.
To echo a bit what others have said: This kind of behavior doesn’t appear to be a major problem in Kotlin (or Java, or other typed languages). You always know when you’re doing Integer math and you always know what type is returned from an expression. Besides being expected behavior, making a mistake often results in a compiler error–this mistake, in particular, is enforced by the type-system. Maybe there is a better way to do things but the motivation for Kotlin would be very different from Python’s.
EDIT: For Kotlin, separate operators for floating and Int division does not add any new information since we already know exactly what kind of division is happening and can’t compile if we try to use the wrong type. However, one might argue that expressions with mixed float/int parts (e.x. x / y / z
, x / y * z
) may return the correct type while still performing unintentional integer math. We still can check exactly what each step is returning and instantly know what is happening–but this could be made more visible.
One solution that requires no change and solves this visibility issue is to have an IDE mark, color, or highlight divisions or expression groups for Integer math mixing with floating point math. I think that feature request has far greater chance of succeeding–you could even make it as a third party plugin.
I like what Dart did with separate division operators:
2 / 5 == 2.5
2 ~/ 5 == 2
But there is no good way to move to something like that now.