val d: Double = 42
When I try to find implicit conversion via intellij, nothing interesting comes up. Also, Int
isn't a subtype of Double
. So how does Scala do it?
We can convert int value to Double object by instantiating Double class or calling Double. valueOf() method.
We can convert double to int in java using typecasting. To convert double data type into int, we need to perform typecasting. Typecasting in java is performed through typecast operator (datatype).
In Scala, Double is a 64-bit floating point number, which is equivalent to Java's double primitive type. The -(x: Double) method is utilized to get the difference of given Double and Double value. Method Definition – def -(x: Char): Double. Returns – Returns the difference of this value and x.
round() method converts the double to an integer by rounding off the number to the nearest integer. For example – 10.6 will be converted to 11 using Math. round() method and 1ill be converted to 10 using typecasting or Double.
Long story short: it's not an ordinary implicit conversion on some companion object, the numerical types get a special treatment.
If we run scala -print
on this script:
val d: Double = 42
we obtain:
package <empty> {
object Main extends Object {
def main(args: Array[String]): Unit = {
new <$anon: Object>();
()
};
def <init>(): Main.type = {
Main.super.<init>();
()
}
};
final class anon$1 extends Object {
private[this] val d: Double = _;
<stable> <accessor> private def d(): Double = anon$1.this.d;
def <init>(): <$anon: Object> = {
anon$1.super.<init>();
anon$1.this.d = 42.0;
()
}
}
}
In the desugared code, we see a double literal 42.0
, but no invocations of any conversion
functions (e.g. from Predef
). Thus, the conversion from Int
to Double
must take place not
at runtime, but at earlier stages of compilation.
The section 3.5.3 of the specification
tells us that Int
weakly conforms to Double
because of the transitivity of the weak conformance relation <:w
:
Int <:w Long <:w Float <:w Double
Furthermore, Section 6.26.1 (Value Conversions)
tells us that rules for numeric widening are applicable if an expression e
of type T
appears in position where an expression of
type pt
is expected and T
weakly conforms to pt
. In this case, we can apply the rule with
e = 42
T = Int
pt = Double
Thus, 42
is converted to 42.0
using toDouble
. Since it's a constant that can be processed at compile time,
we don't see the toDouble
in the desugared code. However, if we desugar a similar program with a non-constant
value
val d: Double = (new scala.util.Random).nextInt(42)
we obtain:
package <empty> {
object Main extends Object {
def main(args: Array[String]): Unit = {
new <$anon: Object>();
()
};
def <init>(): Main.type = {
Main.super.<init>();
()
}
};
final class anon$1 extends Object {
private[this] val d: Double = _;
<stable> <accessor> private def d(): Double = anon$1.this.d;
def <init>(): <$anon: Object> = {
anon$1.super.<init>();
anon$1.this.d = new scala.util.Random().nextInt(42).toDouble();
()
}
}
}
and the toDouble
is there, as specified.
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