Scala FAQ: I’m writing an application and I need to use very large integer or decimal (floating-point) numbers; what’s the best approach?
Solution
Use the Scala BigInt
and BigDecimal
classes. You can create a BigInt
instead of an Int
or Long
:
scala> val b = BigInt(1234567890) b: scala.math.BigInt = 1234567890
or a BigDecimal
instead of a Double
:
scala> val b = BigDecimal(123456.789) b: scala.math.BigDecimal = 123456.789
Unlike their Java equivalents, these classes support all the operators you’re used to using with numeric types:
scala> b + b res0: scala.math.BigInt = 2469135780 scala> b * b res1: scala.math.BigInt = 1524157875019052100 scala> b += 1 scala> println(b) 1234567891
You can convert them to other numeric types:
scala> b.toInt res2: Int = 1234567891 scala> b.toLong res3: Long = 1234567891 scala> b.toFloat res4: Float = 1.23456794E9 scala> b.toDouble res5: Double = 1.234567891E9
To help avoid errors, you can also test them first to see if they can be converted to other numeric types:
scala> b.isValidByte res6: Boolean = false scala> b.isValidChar res7: Boolean = false scala> b.isValidShort res8: Boolean = false scala> if (b.isValidInt) b.toInt res9: AnyVal = 1234567890
Discussion
Although the Scala BigInt
and BigDecimal
classes are backed by the Java BigInteger
and BigDecimal
classes, they are simpler to use than their Java counterparts. As you can see in the examples, they work just like other numeric types, and they’re also mutable (as you saw in the +=
example). These are nice improvements over the Java classes.
Before using BigInt
or BigDecimal
, you can check the maximum values that the other Scala numeric types can handle here:
Data type Range --------- -------------------------------------- Char 16-bit unsigned Unicode character Byte 8-bit signed value Short 16-bit signed value Int 32-bit signed value Long 64-bit signed value Float 32-bit IEEE 754 single precision float Double 64-bit IEEE 754 single precision float
or by checking their MaxValue in the REPL:
scala> Byte.MaxValue res0: Byte = 127 scala> Short.MaxValue res1: Short = 32767 scala> Int.MaxValue res2: Int = 2147483647 scala> Long.MaxValue res3: Long = 9223372036854775807 scala> Double.MaxValue res4: Double = 1.7976931348623157E308
Depending on your needs, you may also be able to use the PositiveInfinity
and NegativeInfinity
of the standard numeric types:
scala> Double.PositiveInfinity res0: Double = Infinity scala> Double.NegativeInfinity res1: Double = -Infinity scala> 1.7976931348623157E308 > Double.PositiveInfinity res45: Boolean = false
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |