## Enteros (Integers)
Los enteros (integers) se pueden dividir ampliamente en dos categorías: enteros sin signo (unsigned integers) y enteros con signo (signed integers). Los enteros con signo son los más utilizados.
> Sin signo (Unsigned) significa que solo puede representar números no negativos (0 y números positivos), mientras que los números con signo (signed) pueden representar tanto números negativos como no negativos.
Los enteros sin signo (unsigned integers) se pueden dividir en cuatro tamaños: 8 bits, 16 bits, 32 bits y 64 bits, representados por `uint8`, `uint16`, `uint32` y `uint64`, respectivamente. Los enteros con signo (signed integers) correspondientes son `int8`, `int16`, `int32` e `int64`. La siguiente tabla muestra los diferentes rangos representados por cada tipo:
| Tipo | Descripción | Rango |
| ------ | ------------------------------------------------- | ------------------------------------------ |
| uint8 | Entero sin signo de 8 bits (8-bit unsigned int) | 0 a 255 |
| int8 | Entero con signo de 8 bits (8-bit signed int) | -128 a 127 |
| uint16 | Entero sin signo de 16 bits (16-bit unsigned int) | 0 a 65535 |
| int16 | Entero con signo de 16 bits (16-bit signed int) | -32768 a 32767 |
| uint32 | Entero sin signo de 32 bits (32-bit unsigned int) | 0 a 4294967295 |
| int32 | Entero con signo de 32 bits (32-bit signed int) | -2147483648 a 2147483647 |
| uint64 | Entero sin signo de 64 bits (64-bit unsigned int) | 0 a 18446744073709551615 |
| int64 | Entero con signo de 64 bits (64-bit signed int) | -9223372036854775808 a 9223372036854775807 |
Tomemos `uint8` e `int8` como ejemplos. Ambos son enteros de 8 bits y pueden representar 256 valores. En el tipo entero sin signo (unsigned integer) `uint8`, el rango que puede representar es de 0 a 255, mientras que en el tipo entero con signo (signed integer) `int8`, el rango que puede representar es de -128 a 127.
Además de los 8 tipos anteriores, existen otros tres tipos enteros especiales, `uint`, `int` y `uintptr`, donde `uint` e `int` pueden representar diferentes rangos en diferentes plataformas, y `uintptr` se utiliza para almacenar direcciones de puntero.
| Tipo | Rango |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `uint` | `uint32` en sistemas de 32 bits, `uint64` en sistemas de 64 bits |
| `int` | `int32` en sistemas de 32 bits, `int64` en sistemas de 64 bits |
| `uintptr` | Tipo entero sin signo (Unsigned integer type) utilizado para almacenar direcciones de puntero, utilizado principalmente en programación de bajo nivel como operaciones inseguras (unsafe operations) |
Ahora, creemos un archivo llamado `integer.go` para demostrar el uso de enteros:
```bash
cd ~/project
touch integer.go
```
package main
import (
"fmt"
"unsafe"
)
func main() {
// View the type of int in the current environment
// Declare a as the type int
var a int
// Use unsafe.Sizeof() to output the memory size occupied by the type
fmt.Printf("The type int in the current environment is %d bits\n", unsafe.Sizeof(a)*8)
var b int8 = 125
// Use the %d placeholder in fmt.Printf to output the value of the integer
// Use the %T placeholder in fmt.Printf to output the type of the variable
fmt.Printf("The value of b is %d, and the type is %T\n", b, b)
// Integer operations
// Declare integers c and d, and calculate their sum
c, d := 2, 3
fmt.Printf("c + d = %d\n", c+d)
// 10 - 5
fmt.Printf("10 - 5 = %d\n", 10-5)
// 8 * 10
fmt.Printf("8 * 10 = %d\n", 8*10)
// Example of uintptr usage - storing an address
var ptr uintptr
x := 42
// Convert the pointer to x to uintptr
ptr = uintptr(unsafe.Pointer(&x))
fmt.Printf("The address of x stored in ptr is: %v\n", ptr)
}
Después de ejecutar el programa, obtenemos la siguiente salida:
go run integer.go
The type int in the current environment is 64 bits
The value of b is 125, and the type is int8
c + d = 5
10 - 5 = 5
8 * 10 = 80
The address of x stored in ptr is: 824634818784
Explicación de la salida:
The type int in the current environment is 64 bits
: Esta línea muestra que el tipo int
en el sistema donde se ejecuta el código es de 64 bits (u 8 bytes), lo que indica que es un int64
. unsafe.Sizeof(a)
devuelve el tamaño de la variable a
en bytes, y multiplicar por 8 lo convierte a bits. Esto significa que el tipo int
puede contener valores enteros más grandes.
The value of b is 125, and the type is int8
: Aquí, hemos declarado una variable b
de tipo int8
y le hemos asignado el valor 125. La salida confirma esto mostrando tanto el valor como el tipo de datos.
c + d = 5
, 10 - 5 = 5
, 8 * 10 = 80
: Estas líneas muestran operaciones aritméticas enteras básicas: suma, resta y multiplicación. La salida confirma los resultados correctos de estos cálculos.
The address of x stored in ptr is: 824634818784
: Esto demuestra cómo se puede usar uintptr
para almacenar una dirección de memoria. Estamos convirtiendo un puntero a la variable entera x
a un tipo uintptr
. El valor real de la dirección variará cada vez que se ejecute el programa. Este es un caso de uso avanzado que se encuentra típicamente en operaciones inseguras (unsafe operations) y programación de sistemas.
En este archivo, la función unsafe.Sizeof()
se puede utilizar para obtener el número de bytes ocupados por el tipo de variable actual. 1 byte (byte) es igual a 8 bits, por lo que unsafe.Sizeof()*8
puede obtener el número de bits ocupados por el tipo. De la salida, podemos ver que el entorno en línea es de 64 bits. El tipo real de int
en el entorno en línea es int64
.
Podemos usar el siguiente comando en la terminal para determinar la arquitectura del sistema actual:
dpkg --print-architecture
amd64