Random.Next() i wyłączna górna granica w C#

Słownik kwalifikacji INF.04 - Projektowanie, programowanie i testowanie aplikacji

Jak działa Random.Next(min, max)?

W C# metoda Random.Next(min, max) losuje liczbę całkowitą z zakresu od min włącznie do max wyłącznie. To bardzo ważne przy pracy z tablicami, napisami i indeksami.

Dla przykładu:

Random random = new Random();
int x = random.Next(0, 5);

Wylosowana wartość x może być równa: 0, 1, 2, 3 albo 4, ale nigdy 5.

Znaczenie w zadaniach egzaminacyjnych

W pokazanym kodzie występuje:

int dlPuli = pulaZnakow.Length - 1;
znak = pulaZnakow[random.Next(0, dlPuli)];

To oznacza, że metoda Next(0, dlPuli) zwróci indeks od 0 do dlPuli - 1. Skoro wcześniej ustawiono:

dlPuli = pulaZnakow.Length - 1;

ostatni znak z napisu pulaZnakow nie będzie nigdy losowany. To częsty błąd typu off-by-one, czyli błąd o 1.

Poprawny zapis

Jeśli chcemy losować dowolny znak z całego napisu, należy użyć:

int dlPuli = pulaZnakow.Length;
znak = pulaZnakow[random.Next(0, dlPuli)];

albo krócej:

znak = pulaZnakow[random.Next(0, pulaZnakow.Length)];

Co warto zapamiętać?

  • dolna granica jest włączna,
  • górna granica jest wyłączna,
  • przy indeksowaniu napisów i tablic najczęściej podaje się Length, a nie Length - 1 jako drugi argument Next().

Typowy błąd

Błędne myślenie: „jeśli ostatni indeks to Length - 1, to taki sam limit trzeba dać do Next()”.

To nieprawda, bo Next() nie losuje wartości równej górnej granicy. Dlatego właśnie w wielu zadaniach egzaminacyjnych trzeba uważnie sprawdzać, czy program obejmuje cały zakres znaków.