how do i compare `Number` for example ```fun Numbe...
# getting-started
s
how do i compare
Number
for example
Copy code
fun Number.comparisionsGreaterThan(i: Number): Boolean {
    return this < i
}
w
I believe because
Number
doesn't implement
Comparable
.
Copy code
/*
 * Copyright 2010-2015 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * <http://www.apache.org/licenses/LICENSE-2.0>
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kotlin

/**
 * Superclass for all platform classes representing numeric values.
 */
public abstract class Number {
    /**
     * Returns the value of this number as a [Double], which may involve rounding.
     */
    public abstract fun toDouble(): Double

    /**
     * Returns the value of this number as a [Float], which may involve rounding.
     */
    public abstract fun toFloat(): Float

    /**
     * Returns the value of this number as a [Long], which may involve rounding or truncation.
     */
    public abstract fun toLong(): Long

    /**
     * Returns the value of this number as an [Int], which may involve rounding or truncation.
     */
    public abstract fun toInt(): Int

    /**
     * Returns the [Char] with the numeric value equal to this number, truncated to 16 bits if appropriate.
     */
    public abstract fun toChar(): Char

    /**
     * Returns the value of this number as a [Short], which may involve rounding or truncation.
     */
    public abstract fun toShort(): Short

    /**
     * Returns the value of this number as a [Byte], which may involve rounding or truncation.
     */
    public abstract fun toByte(): Byte
}
Copy code
public class Int private constructor() : Number(), Comparable<Int> { ... }
s
you can cast to double!
Copy code
fun Number.comparisionsGreaterThan(i: Number) = this.toDouble() < i.toDouble()
s
@Stephan Schroeder would that work for all classes implimenting
Number
in such that all information is preserved and nothing gets truncated as a result?
r
No, of course not. That's why
Number
isn't comparable, why Kotlin doesn't do automatic number conversions, and why different number types exist in the first place.
For a simple example:
Copy code
val x = 21412415121234567L
val y = x + 1
println(x.toDouble() < y.toDouble())

> false
s
;-;
s
that's when you run into NAN (not a number, which is a double). toDouble is defined on Number, so every instance of Number will be able to execute this code. At the same time Double is the type with the highest resolution, so this should work for all current primitive types (signed/unsigned byte, short, int, long, float and double). Of course if you have to deal with e.g. bigger than Double.maxValue BigIntegers than this will stop working. But this is close to the best you can do (you could verify the type of your numbers at runtime and cast accordingly, but this would introduce an overhead that would be be simply unneccessary for all "normal cases). You have to decide if this is good enough. If your application requires t.ex. BigIntegers, maybe compare them directly instead of relying on this method.
ah, ok. I though it would work for long as well. Looks like long.maxValue > double.maxValue.
r
Double is the type with the highest resolution
That's simply not true. In my example, leaving the values as
Long
would return true.
s
you're correct, my mistake
r
Many languages have "automatic widening" that will do this for you, which is why so many people have this idea that doubles can just hold more values. It's unfortunate and technically wrong. Some languages take the difference even further than Kotlin. For example, Rust has a concept of "partial comparability" that floating point values use, since
NaN
isn't actually comparable to anything.
s
if you're willing to take the performance overhead, convert everything to BigDecimal 😎 (i wouldn't, maybe there is a reason why Number isn't Comparable 😉)
🤪 1
😱 1
k
That's still not enough, other people could have written even bigger or more precise
Number
implementations.
You rightfully can't do anything with a
Number
, I'd try to avoid using it at all.
s
ok
so id need 8 (how many functions i have) * (how every many primative number types plus 1 for BigIntegers) function declarations total
if i want to avoid
Number
k
Yes, this is a common frustration simple smile
s
rip
can i alias
<
k
The stdlib solves this problem by actually generating the code.
No, it maps to
.compareTo
.
s
and
<=
>
>=
==
!=
That said, you could just write it like this:
Copy code
fun <T: Comparable<T>> T.comparisionsGreaterThan(other: T): Boolean {
    return this < other
}
s
like alias
isNotEqualTo
to
!=
which resolves to
.compareTo
k
You can do that, see the code I wrote.
s
but arent `String`'s comparable too?
k
Yes, this will include a bunch of other stuff.
s
in which "a" < "b" would not make sence
k
It does make sense, you can do that in Kotin if you want.
s
what happens o.o
k
You can artificially restrict it to
Number
, but that's kind of shady:
Copy code
fun <T> T.comparisionsGreaterThan(other: T): Boolean where T : Comparable<T>, T: Number {
    return this < other
}
s
imma just leave it as comparable...
so this?
Copy code
infix fun <T: Comparable<T>> T.isGreaterThan(i: T) = this > i

infix fun <T: Comparable<T>> T.isGreaterThanOrEqualTo(i: T) = this >= i

infix fun <T: Comparable<T>> T.isLessThan(i: T) = this < i

infix fun <T: Comparable<T>> T.isLessThanOrEqualTo(i: T) = this <= i

infix fun <T: Comparable<T>> T.isEqualTo(i: T) = this == i

infix fun <T: Comparable<T>> T.isNotEqualTo(i: T) = this != i
as even though is intended to be used with numbers, it apparently also can be used with other types that have Comparable so ill just leave it to the user to decide lol
k
Sure, but why does this code exist? It just increases the verbosity.
Also, switch to expression bodies: drop the
: Boolean
,
{}
, and
return
.
That was fast 😛
s
XD
k
Still curious what you're trying to achieve with this.
s
cus remembering what < and > means is confusing lol
k
??? You never did maths?
s
no? o.o
i rarely use them lol
k
Like in school, did you never had a math class or anything like that?
s
i did, but that was years ago lol
k
Try to imagine the
>
thing wanting to "eat" as much as possible, so
2 < 5
because it wants to eat the
5
.
😆 1
r
@karelpeeters I've never heard that one before. That's pretty good.
k
Credit to my first-grade teacher who had a crocodile puppet that ate lego bricks!
👍 1
s
nu
r
I only learned the big number goes on the big side and the little number goes on the little side.
k
Boooring! 😛
r
Agreed