Modulo operacija (liekos): apibrėžimas, pavyzdžiai ir programavimo ypatybės

Sužinokite modulo operacijos (liekos) apibrėžimą, praktinius pavyzdžius ir programavimo niuansus — nuo matematinių pagrindų iki kalbų skirtumų ir techninės įrangos įtakos.

Autorius: Leandro Alegsa

Matematikoje modulo operacijos rezultatas yra aritmetinio dalijimo likutis. Kaip žinoma, aritmetiškai dalijant du sveikuosius skaičius gaunamas kvorentas ir liekana.

Tačiau galimos ir kitokios konvencijos. Kompiuteriuose ir skaičiuotuvuose yra įvairių skaičių saugojimo ir pateikimo būdų. Jų modulo operacijos apibrėžtis priklauso nuo programavimo kalbos ir (arba) techninės įrangos.

Kas yra modulo (liekas)?

Modulo (dažnai žymima kaip a mod n arba operatoriumi % programavimo kalbose) yra veiksmų sritis, kuri grąžina dalijimo likutį. Formaliai, jei a ir n yra sveikieji, tai l yra likutis, kai a dalijama iš n, jei galioja

  • a = q·n + l su tam tikru kvorentu q,
  • 0 ≤ l < |n| (nors šią sąlygą priklausomai nuo konvencijos galima keisti).

Euclidinė (matematinė) konvencija reikalauja, kad liekana būtų neigiama, tik jei daliklis neigiamas — praktiškai dažnai siekiama, kad liekana būtų tarp 0 ir |n|-1 (t. y. neigiama liekana netaikoma).

Matematinė ir programavimo konvencijos

  • Matematikoje: dažniausiai naudojama Euclidinio dalijimo koncepcija — liekana visada nėra neigiama (0 ≤ l < n, jei n > 0).
  • Programavimo kalbose: skirtingos kalbos ir standartai naudoja skirtingas konvencijas:
    • C, C++ (pagal C99 ir vėlesnius), Java: kvorentas gaunamas apvalinant link nulio (truncation toward zero), todėl liekana turi tokį pat ženklą kaip dalinamas (dividend). Pavyzdžiui, C/Java: (-17) % 5 = -2.
    • Python: operatorius % grąžina liekaną, kurios ženklas sutampa su dalikliu (divisor). Taigi Python užtikrina 0 ≤ (a % n) < n, jei n > 0. Pavyzdžiui, (-17) % 5 = 3.
    • JavaScript: operatorius % paima liekaną taip, kaip C (t. y. rezultatas gali būti neigiamas, jeigu dalinamas yra neigiamas); ES specifikacija naudoja likutį pagal atliktą skaičiavimą su plūduriuojančiais taškais.
    • Specifinės funkcijos: daugelis kalbų turi specialias funkcijas darbui su realiais skaičiais — pvz., C matematinėje bibliotekoje yra fmod() (grąžina liekaną pagal trunc(x/y)) ir remainder() (mažina iki artimiausio sveikojo skaičiaus dauginio).

Pavyzdžiai (sveikieji skaičiai)

  • 17 mod 5 = 2 (17 = 3·5 + 2).
  • Matematinė (Euclid) reikšmė: (-17) mod 5 = 3 (nes -17 = (-4)·5 + 3).
  • C/Java stilius (quotient truncated toward zero): (-17) % 5 = -2 (čia kvorentas yra -3, -17 = (-3)·5 + (-2)).
  • Skirtingos kombinacijos:
    • 17 % -5: C/Java → 2, Python → -3 (Python tvarko pagal daliklį, result has same sign as divisor).
    • -17 % -5: C/Java → -2, Python → -2 (abi konvencijos duoda tą patį čia).

Modulo su nevisais skaičiais ir specialios funkcijos

Kai kuriose sistemose galima skaičiuoti likutį ir su plūduriuojančiais skaičiais. Pvz., C funkcija fmod(x,y) grąžina x − n·y, kur n yra sveikasis skaičius, gautas iš x/y apvalinus link nulio. Yra ir kitų funkcijų (pvz., remainder), kurios elgiasi kiek kitaip pagal apvalinimo taisykles.

Naudojimo sritys

  • Laikrodžiai ir datos (ciklinis elgesys): valandos, savaitės dienos.
  • Hash funkcijos ir indeksavimas (pvz., skaičių paskirstymas į ribotą kiekį dėžių).
  • Kryptografinės operacijos (moduliarinė aritmetika RSA, Diffie–Hellman ir kt.).
  • Liekanų testavimas (pvz., tikrinimas, ar skaičius dalijasi iš kito: a mod n == 0).
  • Grafika ir žaidimai (ciklinis judėjimas, darbas su buferiais ir ratu).

Našumo ir optimizavimo pastabos

  • Skaičiavimai su modulo dažnai yra brangesni už paprastą sudėtį ar bitinius veiksmus. Jeigu daliklis yra laipsnis iš dviejų (pvz., 2, 4, 8,...), modulo galima pakeisti bitiniu veiksmu: a & (n−1) (veikia tik su nepriekaištingai teigiamomis sveikojo tipo reikšmėmis ir kai n yra sveika dviejų laipsnio reikšmė).
  • Atkreipkite dėmesį į integro atspindį (signed vs unsigned) — tai gali pakeisti rezultatą ir elgseną C/C++ programose.

Santrauka

Modulo operacija grąžina dalijimo likutį, bet jos interpretravimas gali skirtis: matematinė Euclid konvencija paprastai reikalauja neigiamą liekaną pašalinti (0 ≤ l < |n|), o programavimo kalbose elgsena gali skirtis priklausomai nuo apvalinimo krypties ir kalbos standarto. Todėl rašant kodą ar dokumentaciją svarbu žinoti, kurią konvenciją naudoja jūsų įrankiai ir kokios pasekmės gali kilti, ypač dirbant su neigiamais skaičiais arba plūduriuojančiomis reikšmėmis.



Ieškoti
AlegsaOnline.com - 2020 / 2025 - License CC3