Tipos de datos de Julia

En los lenguajes de programación, hay operaciones matemáticas básicas y cálculos científicos, y sus tipos de datos más comunes sonenterosyde punto flotantenúmeros.

Además, existe un«literal»término llamado «literal» (literal) se utiliza para expresar una notación de un valor fijo en el código fuente; los enteros, los números de punto flotante y las cadenas, etc., son literales.

Por ejemplo:

a=1 // a es una variable, 1 es un literal entero b=1.0 // b es una variable, 1.0 es un literal de punto flotante

Julia proporciona una gran variedad de tipos numéricos primitivos, y sobre ellos define todo un conjunto de operaciones aritméticas; además, ofrece operadores bit a bit y algunas funciones matemáticas estándar.


Tipos de enteros

La siguiente tabla enumera los tipos de enteros que admite Julia:

Tipo ¿Con signo? Número de bits Valor mínimo Valor máximo
Int8 ✓ 8 -2^7 2^7 – 1
UInt8 8 0 2^8 – 1
Int16 ✓ 16 -2^15 2^15 – 1
UInt16 16 0 2^16 – 1
Int32 ✓ 32 -2^31 2^31 – 1
UInt32 32 0 2^32 – 1
Int64 ✓ 64 -2^63 2^63 – 1
UInt64 64 0 2^64 – 1
Int128 ✓ 128 -2^127 2^127 – 1
UInt128 128 0 2^128 – 1
Bool N/A 8 false (0) true (1)

Formas de literales enteros:

Ejemplo

julia> 1
1

julia> 1234
1234

El tipo predeterminado de un literal entero depende de si el sistema de destino tiene arquitectura de 32 o 64 bits (la mayoría de los sistemas actuales son de 64 bits):

Ejemplo

# Sistema de 32 bits:
julia> typeof(1)
Int32

# Sistema de 64 bits:
julia> typeof(1)
Int64

La variable integrada de JuliaSys.WORD_SIZEindica si el sistema de destino tiene arquitectura de 32 o 64 bits:

Ejemplo

# Sistema de 32 bits:
julia> Sys.WORD_SIZE
32

# Sistema de 64 bits:
julia> Sys.WORD_SIZE
64

Julia también define los tipos Int y UInt, que son alias de los tipos de enteros nativos con signo y sin signo del sistema, respectivamente.

Ejemplo

# Sistema de 32 bits:
julia> Int
Int32
julia> UInt
UInt32

# Sistema de 64 bits:
julia> Int
Int64
julia> UInt
UInt64

Comportamiento de desbordamiento

En Julia, superar el valor máximo representable de un tipo provoca un comportamiento de ajuste (wraparound):

Ejemplo

julia> x = typemax(Int64)
9223372036854775807

julia> x + 1
-9223372036854775808

julia> x + 1 == typemin(Int64)
true

Por lo tanto, la aritmética de enteros de Julia es en realidad una forma de aritmética modular, que refleja cómo los ordenadores modernos implementan la aritmética subyacente. En programas donde pueda producirse desbordamiento, es necesario comprobar explícitamente la aparición de ciclos en los límites de los valores máximo y mínimo. De lo contrario, se recomienda utilizar el tipo BigInt de aritmética de precisión arbitraria como alternativa.

A continuación se muestra un ejemplo de comportamiento de desbordamiento y cómo resolverlo:

Ejemplo

julia> 10^19
-8446744073709551616

julia> big(10)^19
10000000000000000000

Errores de división

En las dos siguientes situaciones excepcionales, la división de enteros desencadena un error DivideError:
  • Dividir por cero
  • Dividir por el número negativo más pequeño

remLa función de resto ymodla función de módulo lanzan un error DivideError al dividir por cero; ejemplo:

Ejemplo

julia> mod(1, 0)
ERROR: DivideError: integer division error
Stacktrace:
 [1] div at .\int.jl:260 [inlined]
 [2] div at .\div.jl:217 [inlined]
 [3] div at .\div.jl:262 [inlined]
 [4] fld at .\div.jl:228 [inlined]
 [5] mod(::Int64, ::Int64) at .\int.jl:252
 [6] top-level scope at REPL[52]:1
 
 
julia> rem(1, 0)
ERROR: DivideError: integer division error
Stacktrace:
 [1] rem(::Int64, ::Int64) at .\int.jl:261
 [2] top-level scope at REPL[54]:1

Tipos de punto flotante

La siguiente tabla enumera los tipos de punto flotante que admite Julia:

Tipo Precisión Número de bits
Float16 Precisión media 16
Float32 Precisión simple 32
Float64 Precisión doble 64

Además, el soporte completo para números complejos y racionales se construye sobre estos tipos de datos primitivos.

El formato de los literales de punto flotante se representa a continuación; cuando sea necesario, se puede usarEpara representarlo.

Ejemplo

julia> 1.0
1.0

julia> 1.
1.0

julia> 0.5
0.5

julia> .5
0.5

julia> -1.23
-1.23

julia> 1e10
1.0e10

julia> 2.5e-4
0.00025

Nota:

En la notación científica, para simplificar las fórmulas, se puede usar laEforma con ... para representar. Por ejemplo, 1.03 multiplicado por 10 elevado a la octava potencia se puede abreviar como «1.03E+08», donde «E» es la abreviatura de exponent (exponente).

Los resultados anteriores son todos valores de tipo Float64. Si se usa f en lugar de e, se pueden obtener literales de tipo Float32:

Ejemplo

julia> x = 0.5f0
0.5f0

julia> typeof(x)
Float32

julia> 2.5f-4
0.00025f0
Los valores numéricos se pueden convertir fácilmente alFloat32tipo:

julia> x = Float32(-1.5)
-1.5f0

julia> typeof(x)
Float32

También existen literales de punto flotante hexadecimales, pero solo se aplican a valores de tipo Float64. Generalmente se representan usando el prefijo p y un exponente en base 2:

Ejemplo

julia> 0x1p0
1.0

julia> 0x1.8p3
12.0

julia> x = 0x.4p-1
0.125

julia> typeof(x)
Float64
Julia también admite números de punto flotante de media precisión (Float16), pero se implementan medianteFloat32simulación por software.

julia> sizeof(Float16(4.))
2

julia> 2*Float16(4.)
Float16(8.0)

Guion bajo_Se puede usar como separador de dígitos:

Ejemplo

julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010
(10000, 5.0e-9, 0xdeadbeef, 0xb2)

El cero en los números de punto flotante

Los números de punto flotante tienen dos ceros: el cero positivo y el cero negativo. Son iguales entre sí, pero tienen representaciones binarias diferentes; se puede comprobar con la función bitstring:

Ejemplo

julia> 0.0 == -0.0
true

julia> bitstring(0.0)
"0000000000000000000000000000000000000000000000000000000000000000"

julia> bitstring(-0.0)
"1000000000000000000000000000000000000000000000000000000000000000"

Valores especiales de punto flotante

Hay tres valores estándar de punto flotante específicos que no se corresponden con ningún punto del eje de los números reales:

Float16 Float32 Float64 Nombre Descripción
Inf16 Inf32 Inf Infinito positivo Un número mayor que todos los números de punto flotante finitos
-Inf16 -Inf32 -Inf Infinito negativo Un número menor que todos los números de punto flotante finitos
NaN16 NaN32 NaN No es un número Un valor que no es igual (==) a ningún valor de punto flotante (incluido sí mismo)

A continuación se muestran algunos ejemplos de operaciones con números de punto flotante:

Ejemplo

julia> 1/Inf
0.0

julia> 1/0
Inf

julia> -5/0
-Inf

julia> 0.000001/0
Inf

julia> 0/0
NaN

julia> 500 + Inf
Inf

julia> 500 - Inf
-Inf

julia> Inf + Inf
Inf

julia> Inf - Inf
NaN

julia> Inf * Inf
Inf

julia> Inf / Inf
NaN

julia> 0 * Inf
NaN

julia> NaN == NaN
false

julia> NaN != NaN
true

julia> NaN < NaN
false

julia> NaN > NaN
false

También podemos usar las funciones typemin y typemax:

Ejemplo

julia> (typemin(Float16),typemax(Float16))
(-Inf16, Inf16)

julia> (typemin(Float32),typemax(Float32))
(-Inf32, Inf32)

julia> (typemin(Float64),typemax(Float64))
(-Inf, Inf)

Precisión de la máquina

La mayoría de los números reales no se pueden representar con precisión mediante números de punto flotante, por lo que es necesario conocer la distancia entre dos números de punto flotante representables adyacentes, a la que generalmente se llama precisión de la máquina.

Julia proporciona laepsfunción, que puede dar la diferencia entre 1.0 y el siguiente número de punto flotante que Julia puede representar:

Ejemplo

julia> eps(Float32)
1.1920929f-7

julia> eps(Float64)
2.220446049250313e-16

julia> eps() # Igual que eps(Float64)
2.220446049250313e-16

Estos valores son 2.0^-23 en Float32 y 2.0^-52 en Float64, respectivamente. La función eps también puede aceptar un valor de punto flotante como argumento y devolver la diferencia absoluta entre ese valor y el siguiente valor de punto flotante representable. Es decir, eps(x) produce un valor del mismo tipo que x, y x + eps(x) es exactamente el siguiente valor de punto flotante representable mayor que x:

Ejemplo

julia> eps(1.0)
2.220446049250313e-16

julia> eps(1000.)
1.1368683772161603e-13

julia> eps(1e-27)
1.793662034335766e-43

julia> eps(0.0)
5.0e-324

La distancia entre dos números de punto flotante representables adyacentes no es constante; cuanto menor es el valor, menor es la distancia, y cuanto mayor es el valor, mayor es la distancia. En otras palabras, los números de punto flotante representables son más densos cerca del cero en el eje real y se vuelven cada vez más dispersos, a una velocidad exponencial, a medida que se alejan del cero. Por definición, eps(1.0) es igual a eps(Float64), porque 1.0 es un valor de punto flotante de 64 bits.

Julia también proporciona las funciones nextfloat y prevfloat, que devuelven, respectivamente, el siguiente número de punto flotante representable mayor o menor basado en el argumento:

Ejemplo

julia> x = 1.25f0
1.25f0

julia> nextfloat(x)
1.2500001f0

julia> prevfloat(x)
1.2499999f0

julia> bitstring(prevfloat(x))
"00111111100111111111111111111111"

julia> bitstring(x)
"00111111101000000000000000000000"

julia> bitstring(nextfloat(x))
"00111111101000000000000000000001"

Este ejemplo refleja el principio general de que los números de punto flotante representables adyacentes también tienen representaciones de enteros binarios adyacentes.


Modos de redondeo

Si un número no tiene una representación exacta en punto flotante, debe redondearse a un valor representable adecuado.

El modo predeterminado que usa Julia es siempreRoundNearest, es decir, redondear al valor representable más cercano; este valor redondeado usará la menor cantidad posible de dígitos significativos.

Ejemplo

julia> BigFloat("1.510564889",2,RoundNearest)
1.5

julia> BigFloat("1.550564889",2,RoundNearest)
1.5

julia> BigFloat("1.560564889",2,RoundNearest)
1.5

Literales de 0 y 1

Julia proporciona funciones de literales de 0 y 1, que pueden devolver el tipo específico o el tipo de la variable dada.

FunciónDescripción
zero(x)Literal cero del tipo x o del tipo de la variable x
one(x)Literal uno del tipo x o del tipo de la variable x

Estas funciones se pueden usar en comparaciones numéricas para evitar la sobrecarga innecesaria de conversión de tipos.

Por ejemplo:

Ejemplo

julia> zero(Float32)
0.0f0

julia> zero(1.0)
0.0

julia> one(Int32)
1

julia> one(BigFloat)
1.0

Conversión de tipos

La conversión de tipos consiste en convertir una variable de un tipo a otro tipo de datos. Por ejemplo, si desea almacenar un valor de tipo float en un entero simple, necesita convertir forzosamente el tipo float al tipo int. Puede usar el operador de conversión forzada de tipos para convertir explícitamente un valor de un tipo a otro, como se muestra a continuación:

Julia admite tres tipos de conversión numérica, que difieren en cómo manejan las conversiones inexactas.

Primera forma:

T(x) 
o 
convert(T,x) 

Todo lo anterior convierte x al tipo T.

  • Si T es un tipo de punto flotante, el resultado de la conversión es el valor representable más cercano, que puede ser infinito positivo o negativo.
  • Si T es un tipo entero, se lanza un InexactError cuando x no puede ser representado por el tipo T.

Segunda forma:

x % TTambién se puede convertir el entero x a un tipo entero T, lo que equivale al resultado de x módulo 2^n, donde n es el número de bits de T.

Tercera forma:

Las funciones de redondeo aceptan un argumento opcional de tipo T. Por ejemplo, round(Int,x) esInt(round(x))una versión abreviada de.

Ejemplo

julia> Int8(127)
127

julia> Int8(128)
ERROR: InexactError: trunc(Int8, 128)
Stacktrace:
[...]

julia> Int8(127.0)
127

julia> Int8(3.14)
ERROR: InexactError: Int8(3.14)
Stacktrace:
[...]

julia> Int8(128.0)
ERROR: InexactError: Int8(128.0)
Stacktrace:
[...]

julia> 127 % Int8
127

julia> 128 % Int8
-128

julia> round(Int8,127.4)
127

julia> round(Int8,127.6)
ERROR: InexactError: trunc(Int8, 128.0)
Stacktrace:
[...]
Otras extensiones