Manejo de números en Scala

En este artículo vamos a aprender sobre el manejo de números en Scala. En Scala, los tipos Byte, Short, Int, Long y Char se conocen como tipos integrales porque están representados por enteros o números enteros. Los tipos integrales junto con Double y Float comprenden los tipos numéricos de Scala. Estos tipos numéricos amplían el trait AnyVal, al igual que los tipos Boolean y Unit.

La relación de los tipos de valores predefinidos con AnyVal y Any (así como Nothing) se muestra en la siguiente figura.

Como se muestra en la imagen:
• Todos los tipos numéricos amplían AnyVal.
• Todos los demás tipos en la jerarquía de clases de Scala amplían AnyRef.

Si alguna vez necesita saber los valores exactos de los rangos de datos puede encontrarlos en Scala REPL de la siguiente forma:

Spark y Scala en Databricks: Big Data e ingeniería de datos

Trabajo desde niveles básicos hasta avanzados con RDD y DataFrame.

				
					Char.MinValue.toInt  // 0
Char.MaxValue.toInt  // 65535
Byte.MinValue        // -128
Byte.MaxValue       // +127
Short.MinValue      // −32768
Short.MaxValue      // +32767
Int.MinValue       // −2147483648
Int.MaxValue       // +2147483647
Long.MinValue      // -9,223,372,036,854,775,808
Long.MaxValue      // +9,223,372,036,854,775,807
Float.MinValue     // −3.4028235e38
Float.MaxValue     // +3.4028235e38
Double.MinValue    // -1.7976931348623157e308
Double.MaxValue    // +1.7976931348623157e308
				
			

Guiones bajos en literales numéricas

Scala 2.13 introdujo la capacidad de usar guiones bajos en valores literales numéricos, veamos algunos ejemplos:

				
					// Int
val x = 3_000
val x = 300_000
val x = 3_000_000

// Double
val x = 1_123.45
val x = 1_123.45D
val x = 1_123.45d
val x = 1_234e2 // Resultado 123400.0

// Float
val x = 3_456.7F
val x = 3_456.7f
val x = 1_234e2F

// BigInt y BigDecimal
val x: BigInt = 1_000_000
val x: BigDecimal = 1_234.56
				
			

¿Cómo crear un número a partir de un String?

Puede que en muchas ocasiones deseemos convertir un String a uno de los tipos numéricos de Scala. Para poder realizar esto debemos usar los métodos to* que están disponibles en un String. Veamos cómo realizarlo:

				
					"1".toByte    // Byte = 1
"1".toShort   // Short = 1
"1".toInt     // Int = 1
"1".toLong    // Long = 1
"1".toFloat   // Float = 1.0
"1".toDouble  // Double = 1.0
				
			

Debemos tener cuidado porque estos métodos pueden generar una excepción del tipo NumberFormatException. Veamos un ejemplo:

				
					"azul".toInt  // java.lang.NumberFormatException
				
			

Es posible que se prefiera utilizar los métodos to*Option, que devuelven Some cuando la conversión es exitosa y None cuando la conversión falla:

				
					"1".toByteOption   // Option[Byte] = Some(1)
"1".toShortOption  // Option[Short] = Some(1)
"1".toIntOption    // Option[Int] = Some(1)
"1".toLongOption   // Option[Long] = Some(1)
"1".toFloatOption  // Option[Float] = Some(1.0)
"1".toDoubleOption // Option[Double] = Some(1.0)
"azul".toIntOption  // Option[Int] = None
				
			

Conversión entre tipos numéricos (casting)

A menudo cuando trabajemos con el manejo de números en Scala tendremos que convertir de un tipo numérico a otro, como de Int a Double, Double a Int, o posiblemente una conversión que involucre BigInt o BigDecimal.

Los valores numéricos normalmente se convierten de un tipo a otro con una colección de métodos to*, incluidos toByte, toChar, toDouble, toFloat, toInt, toLong y toShort.

Los valores numéricos se convierten fácilmente en la dirección que se muestra en la siguiente figura:

Veamos algunos ejemplos:

				
					val x: Byte = 1

x.toShort  // Short = 1
x.toInt    // Int = 1
x.toLong   // Long = 1
x.toFloat  // Float = 1.0
x.toDouble // Double = 1.0
				
			

Spark y Scala en Databricks: Big Data e ingeniería de datos

Trabajo desde niveles básicos hasta avanzados con RDD y DataFrame.

asInstanceOf

Dependiendo de las necesidades, podemos hacer un cast usando asInstanceOf:

				
					val x: Byte = 1         // Byte = 1

x.asInstanceOf[Short]   // Short = 1
x.asInstanceOf[Int]     // Int = 1
x.asInstanceOf[Long]    // Long = 1
x.asInstanceOf[Float]   // Float = 1.0
x.asInstanceOf[Double]  // Double = 1.0
				
			

¿Cómo anular el tipo numérico predeterminado?

Cuando se utiliza un estilo de declaración de tipo implícito, Scala asigna automáticamente los tipos de datos en función de sus valores numéricos. Puede suceder que deseemos anular el tipo predeterminado cuando creamos un campo numérico. Por ejemplo, si asigna 1 a una variable sin declarar explícitamente su tipo, Scala le asigna el tipo Int:

				
					scala> val x = 1

x: Int = 1
				
			

Por lo tanto, cuando necesite controlar el tipo, declárelo explícitamente de la siguiente forma:

				
					val x: Byte = 1   // Byte = 1
val x: Short = 1  // Short = 1
val x: Int = 1    // Int = 1
val x: Long = 1   // Long = 1
val x: Float = 1  // Float = 1.0
val x: Double = 1 // Double = 1.0
				
			

Para longs, doubles y floats también puedes usar este estilo:

				
					val x = 1l // Long = 1
val x = 1L // Long = 1
val x = 1d // Double = 1.0
val x = 1D // Double = 1.0
val x = 1f // Float = 1.0
val x = 1F // Float = 1.0
				
			

Manejo de números grandes

El manejo de números en Scala puede ser algo complicado si está escribiendo una aplicación y necesita usar valores enteros o decimales muy grandes.

Si estamos en esta situación y los tipos Long y Double no son lo suficientemente grandes, podemos usar las clases de Scala BigInt y BigDecimal. Veamos a continuación un ejemplo:

				
					val bi = BigInt(1234567890)     // BigInt = 1234567890
val bd = BigDecimal(123456.789) // BigDecimal = 123456.789


// Podemos usar underscores con literales numéricas

val bi = BigInt(1_234_567_890) // BigInt = 1234567890
val bd = BigDecimal(123_456.789) // BigDecimal = 123456.789
				
			

BigInt y BigDecimal admiten todos los operadores que utilizamos con tipos numéricos en Scala:

				
					bi + bi        // BigInt = 2469135780
bi * bi        // BigInt = 1524157875019052100
bi / BigInt(2) // BigInt = 617283945
				
			

Además, podemos convertirlos a otros tipos numéricos:

				
					bi.toInt    // 1234567891
bi.toLong   // 1234567891
bi.toFloat  // 1.23456794E9
bi.toDouble // 1.234567891E9
				
			

¿Cómo generar números aleatorios?

En algunas situaciones puede darse el caso de que necesitemos crear números aleatorios, como cuando probamos una aplicación, realizamos una simulación o cualquier otra situación.

En Scala podemos crear números aleatorios con la clase scala.util.Random. Los siguientes ejemplos muestran casos de uso comunes de generación de números aleatorios:

Spark y Scala en Databricks: Big Data e ingeniería de datos

Trabajo desde niveles básicos hasta avanzados con RDD y DataFrame.

				
					val r = scala.util.Random

// Enteros aleatorios
r.nextInt // -171908677
r.nextInt // 1537432858

// Retornar una valor entre 0.0 y 1.0
r.nextDouble // 0.6442484886442404
r.nextDouble // 0.6725316083201621

// Retornar una valor entre 0.0 y 1.0
r.nextFloat // 0.15001667
r.nextFloat // 0.05077243

// Establecer una semilla cuando se crear un nuevo Random
val r = scala.util.Random(17)

// Actualizar la semilla después de tener una instancia de Random
r.setSeed(89)

// Limitar los enteros a un valor máximo
r.nextInt(4) // 2
r.nextInt(4) // 0
r.nextInt(4) // 3
				
			
Entradas creadas 25

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Publicaciones relacionadas

Comienza escribiendo tu búsqueda y pulsa enter para buscar. Presiona ESC para cancelar.

Volver arriba