I see a lot of questions about this — it’s clearly a source of some confusion.
Part of the problem is that it seems like Number should be such a powerful abstraction. Write the code just once, and it can work for all numeric types! No need to force your choice of Int or Double on everyone (or write umpteen versions of the same code)!
Unfortunately, there are two major problems: one fundamental, one pragmatic.
The fundamental one is that of the result types. If you add, say, a Float and an Int, what type should the result be? There’s no natural answer; whatever you choose, it may not be able to hold the result exactly. And the same problem recurs for all combinations of numeric types, and for most binary operations. (And it gets even harder once you bring in the unsigned types.)
And even if you somehow hard-code the results for all the primitive numeric types, don’t forget that there’s also BigInteger, and BigDecimal, and any other subclasses of Number that you write yourself or find in third-party libraries…
Of course, that’s not a problem for operations upon two numbers of the same type. (Or at least, no more of a problem than we already have.) But that would be a bit restrictive.
The pragmatic problem is that java.lang.Number (to which kotlin.Number is mapped) doesn’t support anything except for a few conversion methods. So it’s not easy for Kotlin to add them. (Again, even if it added lots of extension methods, they wouldn’t be able to cope with new Number subclasses.)
This is all very unfortunate. If java.lang.Number had been designed a bit more imaginatively (e.g. with a type parameter giving the concrete type, and lots more abstract methods), then it could have been far more powerful. But I don’t think it’s possible for Kotlin to retrofit any of that, so we’re pretty much stuck with it.
(Of course, if anyone has any bright ideas, I’d be interested to see them!)