Neuvokaa viisaammat kuinka saan laskettua modulo 103 -algoritmin tarkisteen. Osaan laskea kyllä arvoparien ja niiden painoarvojen tulojen summan, mutta mitäs sitten tapahtuu?
Kuinka modulo 103 lasketaan
sedemik
94076
0Äänestä
Muut lukivat myös
Odottaa vastausta
Näihin keskusteluihin ei ole vielä vastattu. Ole ensimmäinen.
Vastaukset 9
Vanhimmat
Modulo 103 tarkoittaa yksinkertaisesti kokonaislukujaon jakojäännöstä. Osamäärää emme siis halua, vain jakojäännöksen kokonaislukuna.
Ohjelmointikielissä kokonaisjaon jakojäännöstä yleensä merkitään prosenttimerkillä %
Jos lasket suoraan kokonaisluvuilla:
esim.
110 % 103 = 7
koska 110 - 103 = 7
(ja enempää ei voi vähentää)
ja 1 * 103 + 7 = 110 (tarkistus)
300 % 103 = 94
koska 300 - 103 - 103 = 94
(ja enempää ei voi vähentää)
ja 2 * 103 + 94 = 300 (tarkistus)
Jos lasket desimaaliluvuilla
esim.
300 / 103 = 2,912621359223300970873786407767
Kokonaisjaon osamäärä olisi siis 2
300 - 2 * 103 = 94
Joten 300 % 103 = 94
Modulo 103 on siis aina välillä 0 ... 102 (kun puhutaan positiivisista luvuista)
Jos modulo 103 on nolla, on ko. luku (tasan) jaollinen luvulla 103.
Ohjelmointikielissä eroja negatiivisilla luvuilla esim. C laskee:
-10%3 = -1
eli -10 = -3*3 + -1
Python taasen laskee (kongruenssin tapaan):
-10%3 = 2
eli -10 = -4*3 + 2
Yllättäen myös jakolasku menee eri tavalla:
C: -10/3 = -3
Python: -10/3 = -4
Toisaalta wikipediassa lukee: "Kun x ja y ovat kokonaislukuja ja x > y, ne voidaan esittää yhtälönä x = a * y + r, missä a on luonnollinen luku ja 0 < r < |y|. Lukua a kutsutaan usein jakolaskun x/y osamääräksi ja lukua r jakojäännökseksi."
Siis pitää olla x > y ja -10 < 3, joten jakolaskua -10/3 ei kai sitten ole määritelty. Kongruenssissa kuitenkin määritellään myös tapauksia x < y.
Siis miten tää nyt oikein menee?
Jos kaksi kokonaislukua a ja b ovat samat modulo M, merkitään a = b (mod M), niin a-b = kM jollain kokonaisluvulla k. Niiden erotus on siis M:n monikerta.
Nyt C:ssä -10%3 = -1 ja pythonissa -10%3 = 2, mutta selvästihän -1 = 2 (mod 3), koska -1-2=-3=(-1)*3. Määritelmällisesti jos jaetaan x y:llä, niin saadaan x = by+r, jossa jakojäännökselle pätee 0
Englanninkielinen wiki selittää homman:
http://en.wikipedia.org/wiki/Remainder#The_case_of_general_integers
Ja suomenkielinen väärin:
http://fi.wikipedia.org/wiki/Jakojäännös
Niin, ja toi jakolaskuhan menee molemmilla C:llä ja Pythonilla matemaattisesti väärin, oikein tietysti olisi kokonaisluku/kokonaisluku => rationaaliluku tai kokonaisluku jos menee tasan.
Esim. Lispillä menee oikein:
(/ -10 3) => -10/3 (rationaaliluku)
(/ -6 3) => -2 (kokonaisluku)
Lispissä myös jakojäännökselle ja modulolle omat:
(mod -10 3) => 2
(rem -10 3) => -1
Pitänee olla varovainen näiden kanssa...
"Pythonilla matemaattisesti väärin, oikein tietysti olisi kokonaisluku/kokonaisluku => rationaaliluku tai kokonaisluku jos menee tasan. "
Jos ollaan tarkkoja, niin rationaaliluku se on kokonaislukukin, mutta tämä ei ole oleellista. Oleellista on ymmärtää miten tietokoneet toimivat. Kun ymmärtää miten luvut tietokoneessa esitetään sisäisesti, niin näiden pienten ihmeellisyyksien tajuaminen helpottuu huomattavasti. Eli C:ssä tuo varsinainen jakolasku suoritetaan ja tulos tallennetaan niin tarkasti kuin se pystytään - se vaan ei satu aina olemaan tarkka tulos vaan "tarkin mahdollinen". Toisaalta lispin antama -10/3 ei sinällään välttämättä kerro kysyjälle paljoa, kyseinen luku pitää yleensä evaluoida desimaaliluvuksi, jolloin laskutoimitus on tietyssä mielessä "laskettu". Kyseessähän on vastaava tilanne, kuin jos laskin antaisi vastauksen sqrt(2) kysymykseen paljonko on neliöjuuri kakkosesta :)
Kyllä Lispissä on ihan "oikea" tyyppi rationaaliluvuille, eikä sitä muuteta liukuluvuiksi keskinäisissä laskuissa.
Itseasiassa siten että rational-tyypin alaluokkina ovat integer ja ratio (=kaksi kokonaislukua).
Ts. se vastaa tuota "rationaaliluku se on kokonaislukukin"-hommaa.
Testataan Lispissä onko 5 kokonaisluku:
(integerp 5) => T
Onko se rationaaliluku:
(rationalp 5) => T
Entäs reaali- tai kompleksiluku?
(realp 5) => T
(complexp 5) => NIL
Lisäksi se näköjään supistaa automaattisesti ratiot:
(rational 4/6) => 2/3
Ja muuttaa tarvittaessa integer-tyypiksi:
(integerp (rational 6/6)) => T
http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node16.html
Onko ongelmasi siinä, millä tavalla lasketaan se luku, josta tarkistussumma pitäisi laskea, vaiko siinä, miten jakojäännös modulo 103 saadaan kyseisestä luvusta?
HUOM:
Esim. pankkien käyttämien virtuaaliviivakoodien kohdalla käytetään kyseistä algoritmiä ja siellä on jaettava niin isoja lukuja joihin tietokoneet eivät suoraan pysty. Luku on käsiteltävä stringinä ja jaettava osissa. Esim. seuraavasti: ota ekat 9 numeroa, muunna luvuksi ja moduloi se, liitä tulokseen seitsämän seuraavaa numeroa ja moduloi vastaavasti jne. kunnes luku on riittävän pieni moduloitavaksi lopullisesti.