Reszta z dzielenia zdradza, czy liczba jest parzysta. Trzy znaki równości chronią przed pułapką porównań. A operator && potrafi zwrócić coś zupełnie innego niż prawda albo fałsz.

TypeScript arytmetyka porównania logika 45 min
CEL LEKCJI

Czego się dziś nauczysz

  • Użyjesz operatora reszty do sprawdzania podzielności i cykliczności
  • Wyjaśnisz, dlaczego w TypeScripcie porównujemy przez ===, a nie ==
  • Zbudujesz złożony warunek z &&, || i !
  • Przewidzisz wynik wyrażenia, znając kolejność wykonywania działań
  • Zastąpisz krótkie if operatorem warunkowym ? :
TEORIA

Operatory arytmetyczne

OperatorDziałaniePrzykład
+dodawanie (lub sklejanie tekstu)7 + 29
-odejmowanie7 - 25
*mnożenie7 * 214
/dzielenie (zawsze z częścią dziesiętną)7 / 23.5
%reszta z dzielenia7 % 21
**potęgowanie7 ** 249

Dzielenie przez zero nie przerywa programu

5 / 0 daje Infinity, a 0 / 0 daje NaN. W przeciwieństwie do C# nie poleci tu żaden wyjątek — dziwny wynik popłynie dalej przez cały program. Jeśli dzielnik pochodzi od użytkownika, sprawdź go przed dzieleniem.

Zwiększanie i zmniejszanie o jeden

src/index.ts
let licznik = 5;

licznik++;              // 6  — to samo co licznik = licznik + 1
licznik--;              // 5

// różnica między zapisem przed i po nazwie
let a = 5;
console.log(a++);       // wypisze 5, dopiero potem zwiększy (a = 6)

let b = 5;
console.log(++b);       // najpierw zwiększy, wypisze 6

W praktyce ++ stosuje się prawie wyłącznie w pętlach, jako osobną instrukcję. Mieszanie go z wypisywaniem albo obliczeniami to sprawdzony sposób na kod, którego nikt nie zrozumie — łącznie z autorem.

WARTO ZNAĆ

Reszta z dzielenia w akcji

Operator % wygląda niepozornie, a rozwiązuje zaskakująco wiele zadań:

src/index.ts
const n = 27;

// 1. Czy liczba jest parzysta?
const parzysta = n % 2 === 0;              // false

// 2. Ostatnia cyfra liczby
const ostatniaCyfra = n % 10;              // 7

// 3. Czy podzielna przez 3 i przez 5 jednocześnie?
const przez15 = n % 3 === 0 && n % 5 === 0;   // false

// 4. Zamiana sekund na minuty i sekundy
const sekundy = 197;
const min = Math.floor(sekundy / 60);      // 3
const sek = sekundy % 60;                  // 17
console.log(min + " min " + sek + " s");

// 5. Cykliczne przechodzenie po kolorach (0,1,2,0,1,2,…)
const numerUcznia = 7;
const numerGrupy = numerUcznia % 3;        // 1

Wzorzec do zapamiętania

x % n === 0 znaczy „x jest podzielne przez n”. Ten jeden zapis rozwiązuje połowę szkolnych zadań z podzielności, a także klasyczne FizzBuzz.

SKRÓTY

Skrócone przypisania

Zapis skróconyZnaczy to samo coTypowe użycie
suma += 5suma = suma + 5naliczanie punktów
zycie -= 20zycie = zycie - 20obrażenia w grze
cena *= 1.23cena = cena * 1.23doliczenie VAT
ilosc /= 2ilosc = ilosc / 2podział na pół
tekst += "!"tekst = tekst + "!"budowanie napisu
WAŻNE

Porównania — i sprawa trzech znaków równości

OperatorZnaczeniePrzykład
===równe co do wartości i typu5 === 5true
!==różne co do wartości lub typu5 !== "5"true
> <większe / mniejsze3 < 7true
>= <=większe lub równe / mniejsze lub równe7 >= 7true

Dlaczego nie ==

W JavaScripcie istnieje też ==, które przed porównaniem próbuje sprowadzić obie strony do wspólnego typu. Efekty bywają absurdalne:

galeria dziwności ==
console.log("5" == 5);        // true  — tekst zamieniony na liczbę
console.log(0 == false);      // true
console.log("" == 0);         // true
console.log(null == undefined); // true

console.log("5" === 5);       // false — i tak właśnie ma być
console.log(0 === false);     // false

Zasada bez wyjątków

W tym kursie używamy wyłącznie === i !==. W TypeScripcie z włączonym trybem strict porównanie "5" === 5 i tak zostanie zgłoszone jako błąd — kompilator widzi, że te typy nie mają szansy być równe.

Porównywanie tekstów

src/index.ts
console.log("Ala" === "Ala");        // true
console.log("Ala" === "ala");        // false — wielkość liter ma znaczenie
console.log("Ala".toLowerCase() === "ala");   // true — bezpieczne porównanie

console.log("jabłko" < "banan");     // true — porównanie alfabetyczne
console.log("10" < "9");             // true (!) — jako tekst, nie liczba

Ostatnia linia to typowa pułapka przy sortowaniu: tekst "10" jest „mniejszy” od "9", bo porównywanie idzie znak po znaku, a znak 1 stoi w alfabecie przed 9. Liczby porównuj zawsze jako liczby.

TEORIA

Operatory logiczne

OperatorNazwaWynik jest prawdą, gdy…
&&koniunkcja (i)oba warunki są prawdziwe
||alternatywa (lub)przynajmniej jeden warunek jest prawdziwy
!negacja (nie)warunek jest fałszywy
src/index.ts — czy uczeń może iść na wycieczkę
const sredniaOcen = 4.2;
const maZgodeRodzicow = true;
const zaleglosciFinansowe = false;
const liczbaNieobecnosci = 6;

const spelniaWymagania =
  sredniaOcen >= 3.0 &&
  maZgodeRodzicow &&
  !zaleglosciFinansowe &&
  liczbaNieobecnosci < 10;

console.log("Może jechać: " + spelniaWymagania);   // true

Skrócone obliczanie

Operatory logiczne przerywają obliczenia, gdy tylko wynik jest przesądzony. Przy && pierwszy fałsz kończy sprawę — druga strona nie zostanie nawet obliczona:

src/index.ts
const dzielnik = 0;

// druga część nie wykona się wcale, więc nie ma dzielenia przez zero
const bezpiecznie = dzielnik !== 0 && 100 / dzielnik > 5;
console.log(bezpiecznie);   // false

Ta właściwość jest stale wykorzystywana do zabezpieczeń: najpierw sprawdzasz, czy coś w ogóle istnieje, a dopiero potem z tego korzystasz.

Wartości „prawdziwe” i „fałszywe”

W warunku może stanąć nie tylko boolean. Sześć wartości język traktuje jako fałsz, reszta jest prawdą:

wartości fałszywe (falsy)
false     0     ""     null     undefined     NaN

wszystko inne jest prawdziwe — także "0", "false", [] i {}

Uwaga na zero i pusty tekst

Warunek if (liczbaPunktow) nie zadziała dla wyniku 0 punktów — zero jest traktowane jak fałsz. Kiedy sprawdzasz, czy wartość istnieje, pisz wprost: if (liczbaPunktow !== undefined).

TEORIA

Kolejność wykonywania działań

od najwyższego priorytetu
1.  ( )                     nawiasy
2.  !  ++  --               negacja, inkrementacja
3.  **                      potęgowanie
4.  *  /  %                 mnożenie, dzielenie, reszta
5.  +  -                    dodawanie, odejmowanie
6.  <  <=  >  >=            porównania
7.  ===  !==                równość
8.  &&                      koniunkcja
9.  ||                      alternatywa
10. ? :                     operator warunkowy
11. =  +=  -=  *=  /=       przypisanie
to samo z nawiasami i bez
console.log(2 + 3 * 4);        // 14 — mnożenie pierwsze
console.log((2 + 3) * 4);      // 20

const wiek = 17;
const zgoda = true;

// czyta się: (wiek >= 18) || ((wiek >= 16) && zgoda)
console.log(wiek >= 18 || wiek >= 16 && zgoda);   // true

Nie ucz się tej tabeli na pamięć

Zawodowcy jej nie pamiętają — po prostu stawiają nawiasy. Zapis (wiek >= 18) || ((wiek >= 16) && zgoda) działa identycznie, a każdy zrozumie go od pierwszego spojrzenia. Nawiasy nic nie kosztują.

Operator warunkowy

src/index.ts
const punkty = 62;

// warunek ? wartość_gdy_prawda : wartość_gdy_fałsz
const ocena = punkty >= 50 ? "zaliczone" : "niezaliczone";
const doplata = punkty < 50 ? 0 : punkty * 0.5;

console.log(ocena);     // zaliczone
console.log(doplata);   // 31

To jedyny operator w języku, który przyjmuje trzy argumenty. Świetnie nadaje się do wyboru jednej z dwóch wartości. Nie próbuj go zagnieżdżać na trzech poziomach — wtedy lepiej sięgnąć po if z lekcji 8.

PRZYKŁAD Z OMÓWIENIEM

Automat z napojami

Automat sprawdza, czy napój jest dostępny, czy klient wrzucił dość pieniędzy, i wydaje resztę rozbitą na monety.

src/index.ts
// ── stan automatu ──
const cenaNapoju = 3.7;
const sztukWMagazynie = 4;
const automatCzynny = true;

// ── wrzucone pieniądze (w groszach, żeby uniknąć błędów zaokrągleń) ──
const wrzucone = 500;
const cenaGrosze = Math.round(cenaNapoju * 100);

// ── warunki sprzedaży ──
const jestTowar = sztukWMagazynie > 0;
const starczyPieniedzy = wrzucone >= cenaGrosze;
const mozliwaSprzedaz = automatCzynny && jestTowar && starczyPieniedzy;

// ── rozliczenie ──
const resztaGrosze = mozliwaSprzedaz ? wrzucone - cenaGrosze : wrzucone;
const zlotowki = Math.floor(resztaGrosze / 100);
const grosze = resztaGrosze % 100;

console.log("Cena:      " + cenaNapoju.toFixed(2) + " zł");
console.log("Wrzucono:  " + (wrzucone / 100).toFixed(2) + " zł");
console.log("Sprzedaż:  " + (mozliwaSprzedaz ? "OK" : "ODMOWA"));
console.log("Reszta:    " + zlotowki + " zł " + grosze + " gr");
wynik w konsoli
Cena:      3.70 zł
Wrzucono:  5.00 zł
Sprzedaż:  OK
Reszta:    1 zł 30 gr

Trzy decyzje projektowe warte uwagi

  • Grosze zamiast złotówek. Liczby dziesiętne w komputerze są niedokładne (pamiętasz 0.1 + 0.2?). Systemy kasowe liczą w najmniejszej jednostce — w groszach — i dzielą przez 100 dopiero przy wyświetlaniu.
  • Warunki mają nazwy. Zamiast jednego wielkiego wyrażenia mamy trzy nazwane zmienne. Kod czyta się jak zdanie, a przy błędzie od razu wiadomo, który warunek zawiódł.
  • Podział reszty przez / i %. Dzielenie całkowite daje złotówki, reszta z dzielenia daje grosze. Ten sam wzorzec zamienia sekundy na minuty, a minuty na godziny.
ZADANIA

Zadania

ZAD 1Przewidź wynik★☆☆

Zapisz wyniki, potem sprawdź w edytorze.

zagadka.ts
console.log(17 % 5);
console.log(2 + 3 * 4 - 1);
console.log(10 / 4);
console.log(Math.floor(10 / 4));
console.log(true && false || true);
console.log(!(5 > 3));
console.log(8 % 2 === 0 ? "parzysta" : "nieparzysta");
pokaż rozwiązanie
2
13        mnożenie przed dodawaniem: 2 + 12 - 1
2.5
2         część całkowita z dzielenia
true      && ma wyższy priorytet: (true && false) || true
false
parzysta
ZAD 2Stoper★☆☆

Mając liczbę sekund (np. 3725), wypisz czas w formacie 1 h 02 min 05 s. Skorzystaj z Math.floor i %. Zadbaj o to, żeby minuty i sekundy mniejsze od 10 miały wiodące zero.

pokaż rozwiązanie
const wszystkieSekundy = 3725;

const godziny = Math.floor(wszystkieSekundy / 3600);
const minuty = Math.floor((wszystkieSekundy % 3600) / 60);
const sekundy = wszystkieSekundy % 60;

const mm = minuty < 10 ? "0" + minuty : "" + minuty;
const ss = sekundy < 10 ? "0" + sekundy : "" + sekundy;

console.log(godziny + " h " + mm + " min " + ss + " s");

Krótszy sposób na wiodące zero poznasz w następnej lekcji: String(minuty).padStart(2, "0").

ZAD 3Regulamin wypożyczalni★★☆

Klient może wypożyczyć hulajnogę elektryczną, jeśli: ma ukończone 18 lat albo ma co najmniej 16 lat i zgodę opiekuna; nie ma zaległych opłat; oraz na koncie ma minimum 20 zł. Zapisz warunek w jednej zmiennej mozeWypozyczyc, używając nazwanych zmiennych pomocniczych i nawiasów. Przetestuj na trzech różnych zestawach danych.

pokaż przykładowe rozwiązanie
const wiek = 16;
const zgodaOpiekuna = true;
const zalegleOplaty = false;
const saldo = 25.0;

const wiekOk = wiek >= 18 || (wiek >= 16 && zgodaOpiekuna);
const finanseOk = !zalegleOplaty && saldo >= 20;
const mozeWypozyczyc = wiekOk && finanseOk;

console.log("Wiek OK:      " + wiekOk);
console.log("Finanse OK:   " + finanseOk);
console.log("Decyzja:      " + (mozeWypozyczyc ? "ZGODA" : "ODMOWA"));
ZAD 4Rok przestępny★★☆

Rok jest przestępny, gdy dzieli się przez 4, ale nie przez 100 — chyba że dzieli się przez 400. Zapisz ten warunek jako jedno wyrażenie logiczne i sprawdź dla lat 2024, 1900, 2000 i 2023.

pokaż rozwiązanie
const rok = 1900;

const przestepny = (rok % 4 === 0 && rok % 100 !== 0) || rok % 400 === 0;

console.log(rok + ": " + (przestepny ? "przestępny" : "zwykły"));

// 2024 → przestępny   (dzieli się przez 4, nie przez 100)
// 1900 → zwykły       (dzieli się przez 100, ale nie przez 400)
// 2000 → przestępny   (dzieli się przez 400)
// 2023 → zwykły
ZAD 5Suma cyfr★★★

Mając liczbę trzycyfrową w zmiennej (np. 472), wyłuskaj jej poszczególne cyfry, korzystając wyłącznie z operatorów /, % i funkcji Math.floor — bez zamiany na tekst. Wypisz cyfry osobno, ich sumę oraz liczbę zapisaną wspak.

pokaż rozwiązanie
const liczba = 472;

const setki = Math.floor(liczba / 100);        // 4
const dziesiatki = Math.floor(liczba / 10) % 10; // 7
const jednosci = liczba % 10;                  // 2

const suma = setki + dziesiatki + jednosci;    // 13
const wspak = jednosci * 100 + dziesiatki * 10 + setki;  // 274

console.log("Cyfry: " + setki + ", " + dziesiatki + ", " + jednosci);
console.log("Suma cyfr: " + suma);
console.log("Wspak: " + wspak);

Wzorzec „podziel przez potęgę dziesiątki, weź resztę z dzielenia przez 10” wyciąga dowolną cyfrę liczby. Ta sama technika działa w każdym języku programowania i regularnie pojawia się w zadaniach egzaminacyjnych.

PODSUMOWANIE

Co trzeba zapamiętać

  • / zawsze daje wynik dziesiętny; część całkowitą bierzesz przez Math.floor.
  • x % n === 0 to sprawdzenie podzielności; % rozbija też czas i wydaje resztę.
  • Porównuj wyłącznie przez === i !==.
  • && ma wyższy priorytet niż || — ale i tak stawiaj nawiasy.
  • Fałszywe są tylko: false, 0, "", null, undefined, NaN.
  • Złożony warunek rozbijaj na nazwane zmienne — kod staje się samokomentujący.