Reklama 3 tysiące złotych na miesiąc.
To właśnie taki rodzaj błędu może sprawić, że program zawiesi się tuż przed końcem pętli, postać w grze przeniknie przez ścianę, a planowanie podróży czy przyjmowanie leków wymknie się spod kontroli. Wspólnym mianownikiem wszystkich tych sytuacji jest zła interpretacja granic: czy zaczynamy liczyć od zera, czy od jedynki? Czy zakres obejmuje końcowy element, czy już nie? I wreszcie — ile właściwie trwa coś, co zaczyna się w jednym punkcie, a kończy w innym?
W tym artykule przyjrzymy się temu zjawisku z różnych perspektyw. Wyjaśnimy, skąd się bierze błąd off-by-one, dlaczego tak często popełniają go programiści i projektanci gier, oraz pokażemy, że nawet najprostsze czynności — jak liczenie dni i stawianie ogrodzenia wokół działki — mogą paść jego ofiarą.
Skąd się bierze błąd o jeden?
Źródłem błędu off-by-one jest subtelna, ale istotna rozbieżność w sposobie, w jaki postrzegamy granice — zarówno w myśleniu matematycznym, jak i w logice programowania. Wiele pomyłek tego typu wynika z różnic pomiędzy intuicyjnym liczeniem a formalną strukturą danych i operacji, które wykonujemy. Problem zaczyna się tam, gdzie pojawia się potrzeba określenia, co dokładnie mieści się w danym zakresie: czy uwzględniamy punkt początkowy i końcowy, czy tylko wartości między nimi?
Odpowiednie założenia na starcie to podstawaGorodenkoff / Shutterstock
Jedną z najczęstszych przyczyn OBOE jest różnica między liczeniem od zera a liczeniem od jedynki. W życiu codziennym i matematyce często zaczynamy liczyć od 1 — pierwszy dzień, pierwszy punkt, pierwsza osoba. Tymczasem w większości języków programowania tablice indeksowane są od 0. To z pozoru drobna różnica, ale wystarczy, by doprowadzić do pomyłki. Programista chcący przejść przez tablicę o pięciu elementach może przypadkowo użyć zakresu od 0 do 5, co da sześć iteracji zamiast pięciu i wywoła próbę dostępu do nieistniejącego indeksu.
Innym istotnym źródłem błędów jest niejednoznaczność definicji granic zakresu. Czy podając przedział "od 3 do 6", mamy na myśli wszystkie liczby włącznie, czyli 3, 4, 5 i 6? A może tylko liczby pomiędzy — 4 i 5? Tego typu niejasność może skutkować błędnym określeniem liczby elementów, a tym samym — źle działającym kodem lub błędną oceną sytuacji.
OBOE nie wynika z braku wiedzy, lecz raczej z konfliktu między naszymi nawykami myślowymi a precyzyjnymi wymaganiami technicznymi. To błąd, który łatwo przeoczyć, ponieważ często opiera się na intuicji, a nie na jawnej pomyłce. W efekcie program może działać poprawnie w 99 proc. przypadków, a mimo to zawierać subtelny, trudny do wykrycia błąd logiczny.