math/rand/v2.IntN în Go

Returnează un număr întreg aleatoriu din intervalul [0, n): IntN pentru int, plus variantele Int32N, Int64N, UintN, Uint32N, Uint64N.

Sintaxă
import "math/rand/v2"

func IntN(n int) int
func Int32N(n int32) int32
func Int64N(n int64) int64
func UintN(n uint) uint
func Uint32N(n uint32) uint32
func Uint64N(n uint64) uint64

Ce face math/rand/v2.IntN

rand.IntN(n) returnează un întreg aleatoriu între 0 și n-1 inclusiv. Pentru un zar scrii rand.IntN(6) + 1. Variantele Int32N, Int64N, UintN, Uint32N și Uint64N fac același lucru pentru alte tipuri de întregi. Dacă n este ≤ 0, funcțiile cu semn opresc programul cu panic.

Pachetul math/rand/v2 (Go 1.22) înlocuiește vechiul math/rand. Funcțiile de la nivelul pachetului folosesc un generator inițializat aleatoriu la pornire, deci dau alte valori la fiecare rulare și nu trebuie „seed-uite”. Nu mai există rand.Seed. Numele s-au schimbat și ele: vechiul rand.Intn se numește acum rand.IntN.

Pentru o secvență care se repetă identic (teste, simulări reproductibile) creezi propriul generator: r := rand.New(rand.NewPCG(1, 2)). Metodele lui (r.IntN, r.Float64…) au aceleași nume. Pentru parole sau chei folosește crypto/rand, nu math/rand/v2.

Parametri

Parametru Descriere
n Limita superioară, exclusă. Trebuie să fie > 0.

Ce returnează

Un întreg aleatoriu în [0, n), de același tip ca n.

Exemple

Exemplul 1: Aruncarea zarului

Generatorul global este inițializat aleatoriu, deci rezultatul diferă la fiecare rulare.

package main

import (
    "fmt"
    "math/rand/v2"
)

func main() {
    for i := 1; i <= 5; i++ {
        fmt.Printf("Aruncarea %d: %d\n", i, rand.IntN(6)+1)
    }
}

Rezultat posibil (diferă la fiecare rulare)

Aruncarea 1: 6
Aruncarea 2: 3
Aruncarea 3: 5
Aruncarea 4: 5
Aruncarea 5: 1

Exemplul 2: Generator cu seed fix: aceleași numere la fiecare rulare

Cu rand.New(rand.NewPCG(seed1, seed2)) obții o secvență reproductibilă. Rulează programul de două ori și vei vedea aceleași numere.

package main

import (
    "fmt"
    "math/rand/v2"
)

func main() {
    r := rand.New(rand.NewPCG(2026, 10))
    elevi := []string{"Ana", "Mihai", "Ioana", "Radu"}
    for range 3 {
        fmt.Println("La tablă:", elevi[r.IntN(len(elevi))])
    }
    fmt.Println(r.Int64N(1_000_000), r.Uint32N(100))
}

Rezultat

La tablă: Ana
La tablă: Radu
La tablă: Ioana
982117 79

Exemplul 3: Un număr între două limite

Pentru un interval [min, max] adaugi min la IntN(max-min+1). Programul verifică pe 10000 de valori că toate cad în interval.

package main

import (
    "fmt"
    "math/rand/v2"
)

func intre(min, max int) int {
    return min + rand.IntN(max-min+1)
}

func main() {
    ok := true
    for range 10000 {
        n := intre(10, 20)
        if n < 10 || n > 20 {
            ok = false
        }
    }
    fmt.Println("Toate valorile în [10, 20]:", ok)
}

Rezultat

Toate valorile în [10, 20]: true

Greșeli frecvente

  • Scrii rand.Intn sau rand.Seed(...) cu import "math/rand/v2": în v2 funcția se numește IntN, iar Seed nu mai există.
  • Uiți că limita este exclusă: rand.IntN(6) dă 0..5, nu 1..6.
  • Generezi parole sau coduri de acces cu math/rand/v2: nu este sigur criptografic. Folosește crypto/rand.

Comenzi înrudite

  • math/rand/v2.New: Creează generatoare proprii, cu seed: New pornește de la o sursă (NewPCG sau NewChaCha8), iar NewZipf dă valori cu distribuție Zipf.
  • math/rand/v2.N: Funcție generică: returnează o valoare aleatorie din [0, n) de același tip întreg ca n, inclusiv time.Duration.
  • math/rand/v2.Int: Returnează un întreg aleatoriu pe tot domeniul tipului: Int, Int32, Int64 (nenegative) și Uint, Uint32, Uint64.
  • math/rand/v2.Float64: Returnează un număr zecimal aleatoriu uniform din intervalul [0.0, 1.0): Float64 sau Float32.
  • math/rand/v2.Shuffle: Amestecă aleatoriu n elemente, apelând funcția swap pentru a interschimba elementele i și j.