Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert any a number to a long

Suppose I have:

val number:AnyVal

and I know x may be any number (for our purposes, a Float, Double, Int, Long).

What's the easiest way to convert such a number to a Long:

val l = number.toLong   //fails for AnyVal
like image 549
user48956 Avatar asked Oct 29 '13 00:10

user48956


3 Answers

You can cast it to a Number if you know it's definitely going to be a Float, Double, Int, or Long. Then you can call longValue:

val number:AnyVal = 10
val l:Long = number.asInstanceOf[Number].longValue
like image 161
andy Avatar answered Oct 24 '22 13:10

andy


How about:

scala> import scala.util.Try
import scala.util.Try

scala> val i1: Int = 23
i1: Int = 23

scala> val l1: Long = 42
l1: Long = 42

scala> val f1: Float = 14.9f
f1: Float = 14.9

scala> val d1: Double = 14.96
d1: Double = 14.96

scala> val b1: Boolean = true
b1: Boolean = true

scala> List(i1, l1, f1, d1, b1) map (x => Try(x.asInstanceOf[Number].longValue)) foreach (println(_))
Success(23)
Success(42)
Success(14)
Success(14)
Failure(java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number)

scala> List(i1, l1, f1, d1, b1) map (x => Try(x.asInstanceOf[Number].longValue)) foreach (n => println(n.get))
23
42
14
14
java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number
    at $anonfun$1$$anonfun$apply$1.apply$mcJ$sp(<console>:14)
    at $anonfun$1$$anonfun$apply$1.apply(<console>:14)
    at $anonfun$1$$anonfun$apply$1.apply(<console>:14)
    at scala.util.Try$.apply(Try.scala:161)
    at $anonfun$1.apply(<console>:14)
    at $anonfun$1.apply(<console>:14)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at .<init>(<console>:14)
like image 24
Randall Schulz Avatar answered Oct 24 '22 13:10

Randall Schulz


Updated answer for Scala 2.11

My original answer does not work in newer versions of Scala because the implicit conversion to RichLong is no longer available.

This updated version works for numbers via type matching for Number sub-types and also for Strings via an implicit conversion in Scala 2.11:

object LongNumber {
  def cast(number: Any): Long = number match {
    case n: Number => n.longValue()
    case x         => throw new IllegalArgumentException(s"$x is not a number.")
  }

  // Test cases
  def main(args: Array[String]): Unit = {
    val twelveByte:     Byte   = 0x0c
    val twelveString:   String = "12"

    println(s"Converting a long:   ${cast(12L)}")
    println(s"Converting an int:   ${cast(12)}")
    println(s"Converting a double: ${cast(12.0)}")
    println(s"Converting a byte:   ${cast(twelveByte)}")
    println(s"Converting a string: $twelveString")
  }
}

The matching technique is a minor variation on the casting technique used in other answers.

Original answer for older versions of Scala

Attempting implicit conversion to RichLong in a match block seems to work quite nicely:

import scala.runtime.RichLong

...

  def cast(number: Any): Long = number match {
    case n: RichLong => n.toLong
    case x => throw new IllegalArgumentException(s"$x is not a number.")
  }

It might also be possible to add a case for matching a String in numeric format if you wanted to cater for that possibility.

like image 22
richj Avatar answered Oct 24 '22 13:10

richj