Մոդուլո գործողություն

Վիքիպեդիայից՝ ազատ հանրագիտարանից

Մոդուլո գործողություն, թվաբանության մեջ վերադարձնում է բաժանման արդյունքում ստացված մնացորդը՝ նշանով, կամ առանց նշանի։

Տրված են երկու դրական թվեր՝ a և n: a մոդուլո n-ը (համակարգչային գիտության մեջ՝ a mod n) Էվկլիդյան բաժանման մնացորդն է՝ a-ն n-ի բաժանելիս, որտեղ a-ն բաժանելին է, իսկ n-ը՝ բաժանարարը[1]։

Օրինակ, 5 mod 2 արտահայտության արժեքը 1 է, քանի որ 5-ը բաժանված է 2-ի, ունի քանորդ՝ 2, իսկ մնացորդը՝ 1, մինչդեռ «9 mod 3» արտահայտության արժեքը 0 է, քանի որ 9-ը բաժանված է 3-ի, ունի քանորդ՝ 3 և մնացորդ՝ 0 (3-ը 3-ի բազմապատկելուց հետո,երբ պատասխանը հանում ենք 9-ից, ստացվում է 0)։

Սովորաբար այս գործողությունը կատարվում է այնպիսի a-ով և n-ով, որ երկուսն էլ լինեն ամբողջ թվեր, սակայն շատ հաշվողական համակարգեր այժմ թույլ են տալիս a-ի և n-ի այլ տեսակներ։ n-ի ամբողջ թվային մոդուլային գործողության արժեքների միջակայքը 0-ից n-1-ն է ներառյալ (mod 1-ը միշտ 0 է, mod 0-ն որոշված չէ, ինչը կարող է հանգեցնել զրոյով բաժանման սխալի որոշ ծրագրավորման լեզուներում)։

Երբ a-ից կամ n-ից մեկը բացասական է, սահմանումը խախտվում է, և ծրագրավորման լեզուները տարբերվում են նրանով, թե ինչպես են սահմանում համակարգչի տված պատասխանը այդ իրավիճակում։

Սահմանման տարբերակներ[խմբագրել | խմբագրել կոդը]

Մաթեմատիկայում մոդուլո գործողության արդյունքը համարժեքության դաս է (ինչպես օրինակ mod 5 գործողության համար դաս 0 = {0, 5, 10, 15, …}, դաս1 = {1, 6, 11, 16, …} և այլն), և դասի ցանկացած անդամ կարող է ընտրվել որպես դասի ներկայացնող անդամ։ Այնուամենայնիվ, սովորաբար, որպես ներկայացնող ընտրվում է նվազագույն ոչ բացասական ամբողջ թիվը, որը պատկանում է այդ դասին։ Այնուամենայնիվ, հնարավոր են այլ սահմանումներ։

Համակարգիչներն ու հաշվիչներն ունեն թվեր պահելու և ներկայացնելու տարբեր եղանակներ, հետևաբար, մոդուլային գործողության նրանց սահմանումը կախված է ծրագրավորման լեզվից կամ համակարգչի սարքախմբից։

Գրեթե բոլոր հաշվողական համակարգերում q գործակիցը և a-ն բաժանած n-ի մնացորդ r-ը բավարարում են հետևյալ պայմաններին.

Այնուամենայնիվ, սա դեռևս թողնում է նշանի անորոշություն, եթե մնացորդը զրոյական չէ. տեղի է ունենում մնացորդի համար երկու հնարավոր ընտրություն, մեկը բացասական, մյուսը դրական, և երկու հնարավոր ընտրություն գործակիցի համար։ Թվերի տեսության մեջ միշտ ընտրվում է դրական մնացորդը, իսկ հաշվարկում ծրագրավորման լեզուները ընտրում են՝ կախված լեզվից և a-ի կամ n-ի նշաններից։ Ստանդարտ Pascal-ը և ALGOL 68-ը, օրինակ, տալիս են դրական մնացորդ (կամ 0) նույնիսկ բացասական բաժանարարների համար, իսկ որոշ ծրագրավորման լեզուներ, ինչպիսին է C90-ը, թողնում են այն իմպլեմենտացիային, երբ n-ից կամ a-ից որևէ մեկը բացասական՝ a mod 0-ն որոշված չէ համակարգերի մեծ մասում, թեև ոմանք այն սահմանում են որպես a՝

  •      Քանորդ (q) և      մնացորդ (r), որպես ֆունկցիայի բաժանելիներ (a), օգտագործելով կոտորակային մասը կտրելով բաժանում

    Շատ իմպլեմենտացիաներ օգտագործում են կոտորակային մասը կտրելով բաժանում (truncated division), որի համար որպես մնացորդ սահմանվում է․

    ,

    որտեղ []-ը ամբողջ մաս ֆունկցիան է։ Հավասարումից հետևում է, որ մնացորդը ունի նույն նշանը, ինչ բաժանելին․

  • Քանորդ և մնացորդ, օգտագործելով դեպի ներքև կլորացումով բաժանում

    Դոնալդ Կնութը[2] դեպի ներքև կլորացումով բաժանման կողմնակիցն էր, որի համար քանորդը սահմանվում է․

    ,

    որտեղ ⌊⌋-ը դեպի ներքև կլորացման ֆունկցիան է(rounding down). Հավասարումից հետևում է, որ մնացորդը ունի նույն նշանը, ինչ բաժանելին․

  • Քանորդ և մնացորդ, օգատգործելով Էվկլիդյան բաժանում

    Ռայմոնդ Բոութը[3] Էվկլիդյան բաժանման կողմնակիցն էր, որի համաար քանորդը սահմանվում է․

    ,

    որտեղ sgnsgn ֆունկցիան է, ⌊⌋-ը դեպի ներքև կլորացման ֆունկցիան է, և ⌈⌉-ը դեպի վեր կլորացման ֆունկցիան է։Հետևաբար, հավասարումից հետևում է, որ մնացորդը ոչ բացասական է․

  • Քանորդ և մնացորդ, օգտագործելով կլորացումով բաժանում

    Common Lisp-ը և IEEE 754-ը օգտագործում են կլորացումով բաժանում, որի համար քանորդը սահմանվում է․

    որտեղ round-ը կլորացման ֆունկցիան է։ Հետևաբար, մնացորդը ընկած է -ի և -ի միջակայքում, և նշանը համապասախանում է 0-ից աջ կամ ձախ գտնվելուն այդ միջակայքում ․

  • Քանորդ և մնացորդ, օգտագործելով դեպի վերև կլորացումով բաժանում

    Common Lisp-ը նաև օգտագործում է դեպի վեր կլոորացումով բաժանում, որի համար քանորդը սահմանված է․

    ,

    որտեղ ⌈⌉-ը դեպի վեր կլորացման ֆունկցիան է։ Հետևաբար, հավասարումից հետևում է, որ մնացորդը ունի բաժանարարի հակառակ նշանը․

Լեյջենն ասել է․

Բուտը պնդում է, որ էվկլիդեսյան բաժանումը գերազանցում է մյուսներին օրինաչափության և օգտակար մաթեմատիկական հատկությունների առումով, թեև դեպի ներքև կլորացումով բաժանումը, որի կողմնակիցն է Կնուտը, նույնպես լավ սահմանում է։ Չնայած դրա լայն տարածմանը, կոտորակային մասը կտրելով բաժանումը զիջում է մյուս սահմանումներին։
- Division and Modulus for Computer Scientists[4]

Այնուամենայնիվ կոտորակային մասը կտրելով բաժանումը բավարարում է այս նույնությանը .[5]

Նշանը[խմբագրել | խմբագրել կոդը]

Որոշ հաշվիչներ ունեն mod() ֆունկցիայի կոճակ, և շատ ծրագրավորման լեզուներ ունեն նմանատիպ ֆունկցիա, որն արտահայտվում է հիմնականում, որպես mod(a, n)։ Ոմանք որպես նշան օգտագործում են «%», «mod» կամ «Mod» նշանները՝ որպես մոդուլ կամ մնացորդային օպերատոր, օրինակ՝ % n կամ mod n:

Ֆունկցիան չունեցող միջավայրերը կարող են օգտագործել վերը նշված երեք սահմանումներից որևէ մեկը։

Տարածված սխալներ[խմբագրել | խմբագրել կոդը]

Երբ մոդուլային գործողության արդյունքն ունի բաժանելիի նշանը (կոտորակային մասը կտրելով բաժանման սահմանում), դա կարող է հանգեցնել սխալների։

Օրինակ, ստուգելու համար, թե արդյոք ամբողջ թիվը կենտ է, կարելի է հակված լինել ստուգելու, թե արդյոք այդ թիվը 2-ի բաժանելիս մնացորդը հավասար է 1-ի։

bool is_odd(int n) {
    return n % 2 == 1;
}

Այն լեզուներում, որտեղ մնացորդը ունի բաժանելիի նշանը, այս ալգորիթմը կտա սխալ պատասխան, որովհետև, երբ n-ը բաժանելին է և կենտ է, n mod 2 -ը կվերադարձնի −1 և վերևի ֆունկցիան կվերադարձնի false։

Այս խնդիրի լուծման համար ալգորթիմի ճիշտ ալտերնատիվն է ստուգելը, որ մնացորդը 0 չէ (քանի որ, զույգ թվերը 2-ի բաժանելիս մնացորդը 0 է անկախ նշանից)։

bool is_odd(int n) {
    return n % 2 != 0;
}

Մեկ ուրիշ տարբերակ է ստուգելը, որ մնացորդը կամ 1 է, կամ -1։

bool is_odd(int n) {
    return n % 2 == 1 || n % 2 == -1;
}

Ավելի պարզ ալտերնատիվ է վերաբերվելը n% 2-ի արդյունքին, որպես բուլյան արժեք, որտեղ ցանկացած ոչ զրոյական պատասխան վերադարձնում է true:

bool is_odd(int n) {
    return n % 2;
}

Կատարողականության խնդիրներ[խմբագրել | խմբագրել կոդը]

Մոդուլային գործողությունները կարող են իրականացվել այնպես, որ ամեն անգամ հաշվարկվը կատարվի մնացորդով բաժանումով։ Հատուկ դեպքերի համար, որոշ սարքավորումների վրա, կան ավելի արագացված տարբերակներ։ Օրինակ, 2-ի աստիճանների մնացորդը կարող է հաշվվել որպես բիթային AND գործողություն (ենթադրելով, որ x-ը դրական ամբողջ թիվ է կամ օգտագործել բոլոր սահմանումները բացի կոտորակային մասը կտրելով բաժանման սահմանումից)։

x % 2n == x & (2n - 1)

Օրինակներ։

x % 2 == x & 1
x % 4 == x & 3
x % 8 == x & 7

Սարքերում և ծրագրերում, որոնք ավելի արդյունավետ են իրականացնում բիթային գործողությունները, քան մոդուլոն, այս այլընտրանքային ձևերը կարող են արագացնել հաշվարկները[6]։

Կոմպիլյատորների օպտիմիզացիաները կարող են ճանաչել արտահայտություն % հաստատուն գործողությունը, որտեղ հաստատունը երկուսի աստիճան է և ավտոմատ կերպով իրականացնել դրանք որպես արտահայտություն & (հաստատուն-1)՝ թույլ տալով ծրագրավորողին գրել ավելի հստակ կոդ՝ առանց կատարողականությունը վատացնելու։ Այս պարզ օպտիմիզացիան հնարավոր չէ այն լեզուների համար, որոնցում մոդուլային գործողության արդյունքն ունի բաժանելիի նշան (ներառյալ C), բացառությամբ այն դեպքերի, երբ բաժանելին առանց նշանկի ամբողջ թիվ չէ։ Դա պայմանավորված է նրանով, որ եթե բաժանելին բացասական է, մոդուլը բացասական կլինի, մինչդեռ & (հաստատուն-1) արտահայտությունը միշտ դրական կլինի։ Այս լեզուների համար համարժեքը x % 2n == x < 0? x | ~(2n - 1): x & (2n - 1) -ն է,որը օգտագործում է բիթային OR, NOT և AND գործողությունները։

Հատկություններ[խմբագրել | խմբագրել կոդը]

Որոշ մոդուլո գործողություններ կարող են ֆակտորիզացվել և վերլուծվել, ինչպես այլ մաթեմատիկական գործողությունները։ Սա կարող է օգտակար լինել գաղտնագրության ապացույցների մեջ, օրինակ օգտագործվում է Դիֆֆի-Հելլմանի բանալու փոխանակման մեջ։ Այս հատկություններից որոշները պահանջում են, որ a-ն և n-ը լինեն ամբողջ թվեր․

  • Նույնականություն․
    • (a mod n) mod n = a mod n.
    • nx mod n = 0 x-ի բոլոր դրական արժեքների համար.
    • Եթե p-ն պարզ թիվ է, որը b-ի բաժանարար չէ, then abp−1 mod p = a mod p, ըստ Ֆերմայի փոքր թեորեմի.
  • Հակադարձ․
    • [(−a mod n) + (a mod n)] mod n = 0:
    • b−1 mod n նշանակում է մոդուլային բազմապատկվող հակադարձ, որը սահմանվում է, այն և միայն այն դեպքում, երբ b-ն և n-ը համեմատաբար պարզ են, որը տեղի ունի, երբ ձախ կողմը սահմանված է։ [(b−1 mod n)(b mod n)] mod n = 1:
  • Բաշխական․
    • (a + b) mod n = [(a mod n) + (b mod n)] mod n.
    • ab mod n = [(a mod n)(b mod n)] mod n.
  • Բաժանում (սահմանում)․ ab mod n = [(a mod n)(b−1 mod n)] mod n, երբ աջ մասը լավ սահմանված է (երբ b-ն և n-ը փոխադարձաբար պարզ են)։
  • Հակադարձ բազմապատկում․ [(ab mod n)(b−1 mod n)] mod n = a mod n.

Ծրագրավորման լեզուներում[խմբագրել | խմբագրել կոդը]

Մոդուլո գործողությունը տարբեր ծրագրավորման լեզուներում
Լեզու Գործողություն Ամբողջ թիվ Խառը թիվ Սահմանում
ABAP MOD Այո Այո Էվկլիդյան
ActionScript % Այո Ոչ Կոտորակային մասը կտրելով
Ada mod Այո Ոչ Դեպի ներքև կլորացումով[7]
rem Այո Ոչ Կոտորակային մասը կտրելով[7]
ALGOL 68 ÷×, mod Այո Ոչ Էվկլիդյան
AMPL mod Այո Ոչ Կոտորակային մասը կտրելով
APL |[Ն 1] Այո Ոչ Դեպի ներքև կլորացումով
AppleScript mod Այո Ոչ Կոտորակային մասը կտրելով
AutoLISP (rem d n) Այո Ոչ Կոտորակային մասը կտրելով
AWK % Այո Ոչ Կոտորակային մասը կտրելով
bash % Այո Ոչ Կոտորակային մասը կտրելով
BASIC Mod Այո Ոչ Որոշված չէ
bc % Այո Ոչ Կոտորակային մասը կտրելով
C
C++
%, div Այո Ոչ Կոտորակային մասը կտրելով[Ն 2]
fmod (C)
std::fmod (C++)
Ոչ Այո Կոտորակային մասը կտրելով[10]
remainder (C)
std::remainder (C++)
Ոչ Այո Կլորացումով
C# % Այո Այո Կոտորակային մասը կտրելով
Math.IEEERemainder Ոչ Այո Կլորացումով[11]
Clarion % Այո Ոչ Կոտորակային մասը կտրելով
Clean rem Այո Ոչ Կոտորակային մասը կտրելով
Clojure mod Այո Ոչ Դեպի ներքև կլորացումով[12]
rem Այո Ոչ Կոտորակային մասը կտրելով[13]
COBOL FUNCTION MOD Այո Ոչ Դեպի ներքև կլորացումով[Ն 3]
CoffeeScript % Այո Ոչ Կոտորակային մասը կտրելով
%% Այո Ոչ Դեպի ներքև կլորացումով[14]
ColdFusion %, MOD Այո Ոչ Կոտորակային մասը կտրելով
Common Lisp mod Այո Այո Դեպի ներքև կլորացումով
rem Այո Այո Կոտորակային մասը կտրելով
Crystal %, modulo Այո Այո Դեպի ներքև կլորացումով
remainder Այո Այո Կոտորակային մասը կտրելով
D % Այո Այո Կոտորակային մասը կտրելով[15]
Dart % Այո Այո Էվկլիդյան[16]
remainder() Այո Այո Կոտորակային մասը կտրելով[17]
Eiffel \\ Այո Ոչ Կոտորակային մասը կտրելով
Elixir rem/2 Այո Ոչ Կոտորակային մասը կտրելով[18]
Integer.mod/2 Այո Ոչ Դեպի ներքև կլորացումով[19]
Elm modBy Այո Ոչ Դեպի ներքև կլորացումով[20]
remainderBy Այո Ոչ Կոտորակային մասը կտրելով[21]
Erlang rem Այո Ոչ Կոտորակային մասը կտրելով
math:fmod/2 Ոչ Այո Կոտորակային մասը կտրելով
Euphoria mod Այո Ոչ Դեպի ներքև կլորացումով
remainder Այո Ոչ Կոտորակային մասը կտրելով
F# % Այո Այո Կոտորակային մասը կտրելով
Math.IEEERemainder Ոչ Այո Կլորացումով[11]
Factor mod Այո Ոչ Կոտորակային մասը կտրելով
FileMaker Mod Այո Ոչ Դեպի ներքև կլորացումով
Forth mod Այո Ոչ Implementation defined
fm/mod Այո Ոչ Դեպի ներքև կլորացումով
sm/rem Այո Ոչ Կոտորակային մասը կտրելով
Fortran mod Այո Այո Կոտորակային մասը կտրելով
modulo Այո Այո Դեպի ներքև կլորացումով
Frink mod Այո Ոչ Դեպի ներքև կլորացումով
GLSL % Այո Ոչ Որոշված չէ[22]
mod Ոչ Այո Դեպի ներքև կլորացումով[23]
GameMaker Studio (GML) mod, % Այո Ոչ Կոտորակային մասը կտրելով
GDScript (Godot) % Այո Ոչ Կոտորակային մասը կտրելով
fmod Ոչ Այո Կոտորակային մասը կտրելով
posmod Այո Ոչ Դեպի ներքև կլորացումով
fposmod Ոչ Այո Դեպի ներքև կլորացումով
Go % Այո Ոչ Կոտորակային մասը կտրելով[24]
math.Mod Ոչ Այո Կոտորակային մասը կտրելով[25]
big.Int.Mod Այո Ոչ Էվկլիդյան[26]
Groovy % Այո Ոչ Կոտորակային մասը կտրելով
Haskell mod Այո Ոչ Դեպի ներքև կլորացումով[27]
rem Այո Ոչ Կոտորակային մասը կտրելով[27]
Data.Fixed.mod' (GHC) Ոչ Այո Դեպի ներքև կլորացումով
Haxe % Այո Ոչ Կոտորակային մասը կտրելով
HLSL % Այո Այո Որոշված չէ[28]
J |[Ն 1] Այո Ոչ Դեպի ներքև կլորացումով
Java % Այո Այո Կոտորակային մասը կտրելով
Math.floorMod Այո Ոչ Դեպի ներքև կլորացումով
JavaScript
TypeScript
% Այո Այո Կոտորակային մասը կտրելով
Julia mod Այո Այո Դեպի ներքև կլորացումով[29]
%, rem Այո Այո Կոտորակային մասը կտրելով[30]
Kotlin %, rem Այո Այո Կոտորակային մասը կտրելով[31]
mod Այո Այո Դեպի ներքև կլորացումով[32]
ksh % Այո Ոչ Կոտորակային մասը կտրելով
fmod Ոչ Այո Կոտորակային մասը կտրելով
LabVIEW mod Այո Այո Կոտորակային մասը կտրելով
LibreOffice =MOD() Այո Ոչ Դեպի ներքև կլորացումով
Logo MODULO Այո Ոչ Դեպի ներքև կլորացումով
REMAINDER Այո Ոչ Կոտորակային մասը կտրելով
Lua 5 % Այո Այո Դեպի ներքև կլորացումով
Lua 4 mod(x,y) Այո Այո Կոտորակային մասը կտրելով
Liberty BASIC MOD Այո Ոչ Կոտորակային մասը կտրելով
Mathcad mod(x,y) Այո Ոչ Դեպի ներքև կլորացումով
Maple e mod m (by default), modp(e, m) Այո Ոչ Էվկլիդյան
mods(e, m) Այո Ոչ Կլորացումով
frem(e, m) Այո Այո Կլորացումով
Mathematica Mod[a, b] Այո Ոչ Դեպի ներքև կլորացումով
MATLAB mod Այո Ոչ Դեպի ներքև կլորացումով
rem Այո Ոչ Կոտորակային մասը կտրելով
Maxima mod Այո Ոչ Դեպի ներքև կլորացումով
remainder Այո Ոչ Կոտորակային մասը կտրելով
Maya Embedded Language % Այո Ոչ Կոտորակային մասը կտրելով
Microsoft Excel =MOD() Այո Այո Դեպի ներքև կլորացումով
Minitab MOD Այո Ոչ Դեպի ներքև կլորացումով
Modula-2 MOD Այո Ոչ Դեպի ներքև կլորացումով
REM Այո Ոչ Կոտորակային մասը կտրելով
MUMPS # Այո Ոչ Դեպի ներքև կլորացումով
Netwide Assembler (NASM, NASMX) %, div (unsigned) Այո Ոչ Չկա տվյալ
%% (signed) Այո Ոչ Implementation-defined[33]
Nim mod Այո Ոչ Կոտորակային մասը կտրելով
Oberon MOD Այո Ոչ Դեպի ներքև կլորացումով-like[Ն 4]
Objective-C % Այո Ոչ Կոտորակային մասը կտրելով (same as C99)
Object Pascal, Delphi mod Այո Ոչ Կոտորակային մասը կտրելով
OCaml mod Այո Ոչ Կոտորակային մասը կտրելով[34]
mod_float Ոչ Այո Կոտորակային մասը կտրելով[35]
Occam \ Այո Ոչ Կոտորակային մասը կտրելով
Pascal (ISO-7185 and -10206) mod Այո Ոչ Էվկլիդյանի նման[Ն 5]
Programming Code Advanced (PCA) \ Այո Ոչ Որոշված չէ
Perl % Այո Ոչ Դեպի ներքև կլորացումով[Ն 6]
POSIX::fmod Ոչ Այո Կոտորակային մասը կտրելով
Phix mod Այո Ոչ Դեպի ներքև կլորացումով
remainder Այո Ոչ Կոտորակային մասը կտրելով
PHP % Այո Ոչ Կոտորակային մասը կտրելով[37]
fmod Ոչ Այո Կոտորակային մասը կտրելով[38]
PIC BASIC Pro \\ Այո Ոչ Կոտորակային մասը կտրելով
PL/I mod Այո Ոչ Դեպի ներքև կլորացումով (ANSI PL/I)
PowerShell % Այո Ոչ Կոտորակային մասը կտրելով
Programming Code (PRC) MATH.OP - 'MOD; (\)' Այո Ոչ Որոշված չէ
Progress modulo Այո Ոչ Կոտորակային մասը կտրելով
Prolog (ISO 1995) mod Այո Ոչ Դեպի ներքև կլորացումով
rem Այո Ոչ Կոտորակային մասը կտրելով
PureBasic %, Mod(x,y) Այո Ոչ Կոտորակային մասը կտրելով
PureScript `mod` Այո Ոչ Էվկլիդյան[39]
Pure Data % Այո Ոչ Կոտորակային մասը կտրելով (same as C)
mod Այո Ոչ Դեպի ներքև կլորացումով
Python % Այո Այո Դեպի ներքև կլորացումով
math.fmod Ոչ Այո Կոտորակային մասը կտրելով
Q# % Այո Ոչ Կոտորակային մասը կտրելով[40]
R %% Այո Այո Դեպի ներքև կլորացումով[41]
Racket modulo Այո Ոչ Դեպի ներքև կլորացումով
remainder Այո Ոչ Կոտորակային մասը կտրելով
Raku % Ոչ Այո Դեպի ներքև կլորացումով
RealBasic MOD Այո Ոչ Կոտորակային մասը կտրելով
Reason mod Այո Ոչ Կոտորակային մասը կտրելով
Rexx // Այո Այո Կոտորակային մասը կտրելով
RPG %REM Այո Ոչ Կոտորակային մասը կտրելով
Ruby %, modulo() Այո Այո Դեպի ներքև կլորացումով
remainder() Այո Այո Կոտորակային մասը կտրելով
Rust % Այո Այո Կոտորակային մասը կտրելով
rem_euclid() Այո Այո Էվկլիդյան[42]
SAS MOD Այո Ոչ Կոտորակային մասը կտրելով
Scala % Այո Ոչ Կոտորակային մասը կտրելով
Scheme modulo Այո Ոչ Դեպի ներքև կլորացումով
remainder Այո Ոչ Կոտորակային մասը կտրելով
Scheme R6RS mod Այո Ոչ Էվկլիդյան[43]
mod0 Այո Ոչ Կլորացումով[43]
flmod Ոչ Այո Էվկլիդյան
flmod0 Ոչ Այո Կլորացումով
Scratch mod Այո Այո Դեպի ներքև կլորացումով
Seed7 mod Այո Այո Դեպի ներքև կլորացումով
rem Այո Այո Կոտորակային մասը կտրելով
SenseTalk modulo Այո Ոչ Դեպի ներքև կլորացումով
rem Այո Ոչ Կոտորակային մասը կտրելով
sh (POSIX) (includes bash, mksh, &c.) % Այո Ոչ Կոտորակային մասը կտրելով (same as C)[44]
Smalltalk \\ Այո Ոչ Դեպի ներքև կլորացումով
rem: Այո Ոչ Կոտորակային մասը կտրելով
Snap! mod Այո Ոչ Դեպի ներքև կլորացումով
Spin // Այո Ոչ Դեպի ներքև կլորացումով
Solidity % Այո Ոչ Դեպի ներքև կլորացումով
SQL (SQL:1999) mod(x,y) Այո Ոչ Կոտորակային մասը կտրելով
SQL (SQL:2011) % Այո Ոչ Կոտորակային մասը կտրելով
Standard ML mod Այո Ոչ Դեպի ներքև կլորացումով
Int.rem Այո Ոչ Կոտորակային մասը կտրելով
Real.rem Ոչ Այո Կոտորակային մասը կտրելով
Stata mod(x,y) Այո Ոչ Էվկլիդյան
Swift % Այո Ոչ Կոտորակային մասը կտրելով[45]
remainder(dividingBy:) Ոչ Այո Կլորացումով[46]
truncatingRemainder(dividingBy:) Ոչ Այո Կոտորակային մասը կտրելով[47]
Tcl % Այո Ոչ Դեպի ներքև կլորացումով
tcsh % Այո Ոչ Կոտորակային մասը կտրելով
Torque % Այո Ոչ Կոտորակային մասը կտրելով
Turing mod Այո Ոչ Դեպի ներքև կլորացումով
Verilog (2001) % Այո Ոչ Կոտորակային մասը կտրելով
VHDL mod Այո Ոչ Դեպի ներքև կլորացումով
rem Այո Ոչ Կոտորակային մասը կտրելով
VimL % Այո Ոչ Կոտորակային մասը կտրելով
Visual Basic Mod Այո Ոչ Կոտորակային մասը կտրելով
WebAssembly i32.rem_u, i64.rem_u (unsigned) Այո Ոչ Չկա տվյալ[48]
i32.rem_s, i64.rem_s (signed) Այո Ոչ Կոտորակային մասը կտրելով[49]
x86 assembly IDIV Այո Ոչ Կոտորակային մասը կտրելով
XBase++ % Այո Այո Կոտորակային մասը կտրելով
Mod() Այո Այո Դեպի ներքև կլորացումով
Zig %,

@mod, @rem

Այո Այո Կոտորակային մասը կտրելով[50]
Z3 theorem prover div, mod Այո Ոչ Էվկլիդյան

Շատ համակարգչային համակարգեր ապահովում են divmod ֆունկցիոնալություն, որը վերադարձնում է քանորդը և մնացորդը միաժամանակ։ Օրինակները ներառում են x86 ճարտարապետության IDIV հրահանգը, C ծրագրավորման լեզվի div() ֆունկցիան և Pythondivmod() ֆունկցիան։

Ընդհանրացումներ[խմբագրել | խմբագրել կոդը]

Մոդուլոն լրացյալով[խմբագրել | խմբագրել կոդը]

Երբեմն օգտակար է, որ մոդուլոյի արդյունքը ընկած լինի ոչ թե 0-ի և n-1-ի, այլ d-ի և d + n-1-ի միջև։ Այդ դեպքում d-ն կոչվում է լրացյալ։ Թվում է, թե այս գործողության համար ստանդարտ նշում չկա, ուստի եկեք պայմանականորեն օգտագործենք a modd n-ը։ Այսպիսով, մենք ունենք հետևյալ սահմանումը. x mod n = a mod n, երբ d ≤ x ≤ d + n − 1 և x mod n = a mod n: Ակնհայտ է, որ սովորական մոդոյի գործողությունը համապատասխանում է զրո լրացյալին. a mod n = a mod0 n: Լրացյալով մոդուլոյի աշխատանքը կապված է դեպի ներքև կլորացման ֆունկցիայի հետ հետևյալ կերպ.

Լրացյալով մոդուլոն a modd n իմպլեմենտացված է Mathematica լեզվում, որպես Mod[a, n, d] .[51]

Մոդուլո գործողության իմպլեմենտացիան, օգտագործելով կոտորակային մասը կտրելով բաժանում[խմբագրել | խմբագրել կոդը]

Չնայած Կնութի Դեպի ներքև կլորացումով բաժանման և Էվկլիդյան բաժանման մաթեմատիկական գեղեցությանը, ծրագրավորման լեզուներում ընդհանուր առմամբ շատ ավելի տարածված է բաժանման վրա հիմնված մոդուլ գտնելը։ Լեյջենը տրամադրում է հետևյալ ալգորիթմները կոտորակային մասը կտրելով ամբողջ թվի բաժանումը հաշվարկելու համար[4].

/* Euclidean and Floored divmod, in the style of C's ldiv() */
typedef struct {
  /* This structure is part of the C stdlib.h, but is reproduced here for clarity */
  long int quot;
  long int rem;
} ldiv_t;

/* Euclidean division */
inline ldiv_t ldivE(long numer, long denom) {
  /* The C99 and C++11 languages define both of these as truncating. */
  long q = numer / denom;
  long r = numer % denom;
  if (r < 0) {
    if (denom > 0) {
      q = q - 1;
      r = r + denom;
    } else {
      q = q + 1;
      r = r - denom;
    }
  }
  return (ldiv_t){.quot = q, .rem = r};
}

/* Floored division */
inline ldiv_t ldivF(long numer, long denom) {
  long q = numer / denom;
  long r = numer % denom;
  if ((r > 0 && denom < 0) || (r < 0 && denom > 0)) {
    q = q - 1;
    r = r + denom;
  }
  return (ldiv_t){.quot = q, .rem = r};
}

Երկու դեպքում էլ մնացորդը կարող է հաշվարկվել քանորդից անկախ, բայց ոչ հակառակը։

Ծանոթագրություններ[խմբագրել | խմբագրել կոդը]

  1. Weisstein, Eric W. «Congruence». mathworld.wolfram.com (անգլերեն). Վերցված է 2020 թ․ օգոստոսի 27-ին.
  2. Knuth, Donald. E. (1972). The Art of Computer Programming. Addison-Wesley.
  3. Boute, Raymond T. (1992 թ․ ապրիլ). «The Euclidean definition of the functions div and mod». ACM Transactions on Programming Languages and Systems. ACM Press (New York, NY, USA). 14 (2): 127–144. doi:10.1145/128861.128862. hdl:1854/LU-314490. S2CID 8321674.
  4. 4,0 4,1 Leijen, Daan (2001 թ․ դեկտեմբերի 3). «Division and Modulus for Computer Scientists» (Document). {{cite document}}: Cite document requires |publisher= (օգնություն); Unknown parameter |access-date= ignored (օգնություն); Unknown parameter |url= ignored (օգնություն)
  5. Peterson, Doctor (2001 թ․ հուլիսի 5). «Mod Function and Negative Numbers». Math Forum - Ask Dr. Math. Արխիվացված է օրիգինալից 2019 թ․ հոկտեմբերի 22-ին. Վերցված է 2019 թ․ հոկտեմբերի 22-ին.
  6. Horvath, Adam (2012 թ․ հուլիսի 5). «Faster division and modulo operation - the power of two».
  7. 7,0 7,1 «ISO/IEC 8652:2012 - Information technology — Programming languages — Ada». ISO, IEC. 2012. sec. 4.5.5 Multiplying Operators. {{cite journal}}: Cite journal requires |journal= (օգնություն)
  8. «C99 specification (ISO/IEC 9899:TC2)» (PDF). 2005 թ․ մայիսի 6. sec. 6.5.5 Multiplicative operators. Վերցված է 2018 թ․ օգոստոսի 16-ին.
  9. «ISO/IEC 14882:2003: Programming languages – C++». International Organization for Standardization (ISO), International Electrotechnical Commission (IEC). 2003. sec. 5.6.4. «the binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined» {{cite journal}}: Cite journal requires |journal= (օգնություն)
  10. «ISO/IEC 9899:1990: Programming languages – C». ISO, IEC. 1990. sec. 7.5.6.4. «The fmod function returns the value x - i * y, for some integer i such that, if y is nonzero, the result has the same sign as x and magnitude less than the magnitude of y {{cite journal}}: Cite journal requires |journal= (օգնություն)
  11. 11,0 11,1 dotnet-bot. «Math.IEEERemainder(Double, Double) Method (System)». learn.microsoft.com (ամերիկյան անգլերեն). Վերցված է 2022 թ․ հոկտեմբերի 4-ին.
  12. «clojure.core - Clojure v1.10.3 API documentation». clojure.github.io. Վերցված է 2022 թ․ մարտի 16-ին.
  13. «clojure.core - Clojure v1.10.3 API documentation». clojure.github.io. Վերցված է 2022 թ․ մարտի 16-ին.
  14. CoffeeScript operators
  15. «Expressions - D Programming Language». dlang.org. Վերցված է 2021 թ․ հունիսի 1-ին.
  16. «operator % method - num class - dart:core library - Dart API». api.dart.dev. Վերցված է 2021 թ․ հունիսի 1-ին.
  17. «remainder method - num class - dart:core library - Dart API». api.dart.dev. Վերցված է 2021 թ․ հունիսի 1-ին.
  18. «Kernel — Elixir v1.11.3». hexdocs.pm. Վերցված է 2021 թ․ հունվարի 28-ին.
  19. «Integer — Elixir v1.11.3». hexdocs.pm. Վերցված է 2021 թ․ հունվարի 28-ին.
  20. «Basics - core 1.0.5». package.elm-lang.org. Վերցված է 2022 թ․ մարտի 16-ին.
  21. «Basics - core 1.0.5». package.elm-lang.org. Վերցված է 2022 թ․ մարտի 16-ին.
  22. «GLSL Language Specification, Version 4.50.7» (PDF). section 5.9 Expressions. «If both operands are non-negative, then the remainder is non-negative. Results are undefined if one or both operands are negative.»
  23. «GLSL Language Specification, Version 4.50.7» (PDF). section 8.3 Common Functions.
  24. «The Go Programming Language Specification - The Go Programming Language». go.dev. Վերցված է 2022 թ․ փետրվարի 28-ին.
  25. «math package - math - pkg.go.dev». pkg.go.dev. Վերցված է 2022 թ․ փետրվարի 28-ին.
  26. «big package - math/big - pkg.go.dev». pkg.go.dev. Վերցված է 2022 թ․ փետրվարի 28-ին.
  27. 27,0 27,1 «6 Predefined Types and Classes». www.haskell.org. Վերցված է 2022 թ․ մայիսի 22-ին.
  28. «Operators». Microsoft. Վերցված է 2021 թ․ հուլիսի 19-ին. «The % operator is defined only in cases where either both sides are positive or both sides are negative. Unlike C, it also operates on floating-point data types, as well as integers.»
  29. «Mathematics · The Julia Language». docs.julialang.org. Վերցված է 2021 թ․ նոյեմբերի 20-ին.
  30. «Mathematics · The Julia Language». docs.julialang.org. Վերցված է 2021 թ․ նոյեմբերի 20-ին.
  31. «rem - Kotlin Programming Language». Kotlin (անգլերեն). Վերցված է 2021 թ․ մայիսի 5-ին.
  32. «mod - Kotlin Programming Language». Kotlin (անգլերեն). Վերցված է 2021 թ․ մայիսի 5-ին.
  33. «Chapter 3: The NASM Language». NASM - The Netwide Assembler version 2.15.05.
  34. «OCaml library : Stdlib». ocaml.org. Վերցված է 2022 թ․ փետրվարի 19-ին.
  35. «OCaml library : Stdlib». ocaml.org. Վերցված է 2022 թ․ փետրվարի 19-ին.
  36. Perl documentation
  37. «PHP: Arithmetic Operators - Manual». www.php.net. Վերցված է 2021 թ․ նոյեմբերի 20-ին.
  38. «PHP: fmod - Manual». www.php.net. Վերցված է 2021 թ․ նոյեմբերի 20-ին.
  39. «EuclideanRing».
  40. QuantumWriter. «Expressions». docs.microsoft.com (ամերիկյան անգլերեն). Վերցված է 2018 թ․ հուլիսի 11-ին.
  41. «R: Arithmetic Operators». search.r-project.org. Վերցված է 2022 թ․ դեկտեմբերի 24-ին.
  42. «F32 - Rust».
  43. 43,0 43,1 «r6rs.org». Արխիվացված է օրիգինալից 2018 թ․ մարտի 15-ին. Վերցված է 2023 թ․ օգոստոսի 22-ին.
  44. «Shell Command Language». pubs.opengroup.org. Վերցված է 2021 թ․ փետրվարի 5-ին.
  45. «Apple Developer Documentation». developer.apple.com. Վերցված է 2021 թ․ նոյեմբերի 20-ին.
  46. «Apple Developer Documentation». developer.apple.com. Վերցված է 2021 թ․ նոյեմբերի 20-ին.
  47. «Apple Developer Documentation». developer.apple.com. Վերցված է 2021 թ․ նոյեմբերի 20-ին.
  48. «Numerics — WebAssembly 1.1 (Draft 2022-03-02)». webassembly.github.io. Վերցված է 2022 թ․ մարտի 16-ին.
  49. «Numerics — WebAssembly 1.1 (Draft 2022-03-02)». webassembly.github.io. Վերցված է 2022 թ․ մարտի 16-ին.
  50. «Zig Documentation». Zig Programming Language. Վերցված է 2022 թ․ դեկտեմբերի 18-ին.
  51. «Mod». Wolfram Language & System Documentation Center. Wolfram Research. 2020. Վերցված է 2020 թ․ ապրիլի 8-ին.

Նշումներ[խմբագրել | խմբագրել կոդը]

  1. 1,0 1,1 Argument order reverses, i.e., α|ω computes , the remainder when dividing ω by α.
  2. C99 and C++11 define the behavior of % to be truncated.[8] The standards before then leave the behavior implementation-defined.[9]
  3. As implemented in ACUCOBOL, Micro Focus COBOL, and possible others.
  4. Divisor must be positive, otherwise undefined.
  5. As discussed by Boute, ISO Pascal's definitions of div and mod do not obey the Division Identity of D = d · (D / d) + D % d, and are thus fundamentally broken.
  6. Perl usually uses arithmetic modulo operator that is machine-independent. For examples and exceptions, see the Perl documentation on multiplicative operators.[36]

Արտաքին հղումներ[խմբագրել | խմբագրել կոդը]

  • Modulorama, բազմապատկման աղյուսակների անիմացիոն ցուցադրում (բացատրված է ֆրանսերենով)