Tracks
/
Rust
Rust
/
Temario
/
Números enteros
Nú

Números enteros en Rust

1 ejercicio

Acerca de Números enteros

Los números enteros no tienen parte fraccionaria ni decimal. Se representan en la máquina como un patrón de bits binarios.

Los enteros pueden tener signo o no. Tener signo significa reservar uno de los bits del número para indicar si ese número es negativo o no.

Todos los enteros tienen un ancho de bits, que no es más que el número de bits que componen ese número. Esto afecta al valor máximo que puede representar ese tipo de entero.

Por ejemplo, uno de los tipos de entero más comunes es u8: un entero de 8 bits sin signo. Quizá reconozcas este tipo como un único byte. Tiene un valor mínimo de 0 y un valor máximo de 255.

Rust tiene 12 tipos primitivos de entero, desglosados por ancho de bits y por signo:

Sin signo Con signo
u8 i8
u16 i16
u32 i32
u64 i64
u128 i128
usize isize

El ancho de bits de un entero siempre viene indicado por el número que sigue a la u o a la i. usize e isize son especiales: tienen el mismo ancho que un puntero en la máquina de destino. Esto significa que, en una arquitectura de 64 bits, usize e isize ocupan 64 bits, pero en una arquitectura de 32 bits ocupan 32 bits.

¿Cuál debería usar?

En general, si solo necesitas representar algún número, usa un i32: 32 bits abarcan un rango lo bastante amplio como para que sea relativamente improbable que se desborde, y los números con signo dan menos sorpresas que los números sin signo. i32 equivale a un long de C o a un int de Java. Si usas un literal numérico y no anotas el tipo explícitamente, se usará i32 de forma predeterminada.

Si trabajas con datos binarios, lo más sencillo es trabajar con bytes: &[u8] o Vec<u8>.

Rust usa usize para el tamaño y la indexación de las colecciones. Esto se debe a que un ordenador solo puede direccionar, en teoría, usize::MAX bytes de memoria, así que no son posibles colecciones en memoria más grandes. Por lo tanto, usize puede resultarte útil si trabajas mucho con colecciones.

Si tus datos no caben en un entero de 32 bits, plantéate pasar a un entero de 64 o de 128 bits. Si tus datos no caben en un entero de 128 bits, puedes usar un tipo de entero grande como el que ofrece num-bigint.

Los enteros de 16 bits no son muy comunes, pero pueden ser útiles cuando el objetivo son ciertos microcontroladores.

Si sabes que tu aplicación no tiene casos negativos válidos, es mejor usar un entero sin signo en lugar de uno con signo. Contar es un buen ejemplo de esto.

Conversión entre enteros

Rust no tiene conversiones numéricas implícitas. Si necesitas convertir entre tipos de entero, hay dos estrategias básicas: la palabra clave as y los traits From y TryFrom.

Usar la palabra clave as es sencillo: expr as Type. Sin embargo, hay una serie de advertencias y sutilezas que debes tener en cuenta al usar conversiones con as.

La conversión basada en traits es algo más laboriosa, pero también más segura: los traits de conversión solo se implementan donde son seguros. Por ejemplo, i32 implementa From<u8>, From<u16>, From<i8> y From<i16>: cualquier valor representable por cualquiera de estos tipos tiene garantizado ser representable en un i32. Se puede usar como i32::from(expr), o expr.into(), donde expr se resuelve a uno de esos tipos. i32 también implementa TryFrom<u32>, TryFrom<u64>, TryFrom<u128>, TryFrom<usize>, TryFrom<i64>, TryFrom<i128> y TryFrom<isize>. Estas conversiones tendrán éxito o se desbordarán de forma explícita, según el valor. Para usarlas, tendrás que importar los traits std::convert::TryFrom o std::convert::TryInto según corresponda, y luego usar i32::try_from(expr) o expr.try_into(), donde expr se resuelve a un tipo adecuado.

En general, se prefiere la conversión basada en traits a la conversión con as, sobre todo al convertir de un tipo más ancho a uno más estrecho. La conversión basada en traits es un poco más costosa que la conversión con as, aunque de forma irrelevante: usar as por motivos de rendimiento no merece la pena salvo en un bucle extremadamente crítico.

Editar en GitHub El enlace se abre en una nueva ventana o pestaña