Tuskastuin VB:n rajoitteisiin ja kysynkin, mikä olisi helppo ja tehokas kieli pitkillä luvuilla laskentaan. Helpolla tarkoitan helppoa siirtymistä VB:stä ko. kieleen.
Python. Helppo kieli ja pitkät luvut sisäänrakennettuina
def kertoma(n): k = 1 for i in range(1,n+1): k = k*i return k print kertoma(1000)
no toihan on helppo kieli :o ei hirveän tyypitetty kieli ole ei... edes n-muuttujaa ei alusteta numeroksi :o
Tommittaja kirjoitti:
no toihan on helppo kieli :o ei hirveän tyypitetty kieli ole ei... edes n-muuttujaa ei alusteta numeroksi :o
Python tuli minullekin ensimmäisenä mieleen. On helppoa, varsinkin jos on aiemminkin ohjelmoinut. Tehokkuudesta toki voisi joku alkaa väittelemään.
Varmaan kaikille suosituimmille kielille löytyy jonkinlainen kirjasto isoilla numeroilla laskemiseen, jos sitä ei ole kielen sisään rakennettu. Jos C/C++ kiinnostaa, niin kannattaa vilkaista GMP:tä (http://gmplib.org/).
Kiitos nopeista vastauksista. Pythonia olen tainnut kokeillakin mutta sitten jäänyt homma kesken. Laskentatehokin olisi melko tärkeä ominaisuus eikä Python taida niitä nopeimpia olla. Mutta helppous on myös tärkeä ominaisuus kun tässä iässä ei mitään hankalia kieliä jaksa opiskella. C/C++ olen myös joskus tutkaillut mutta melkoisen sivumäärän jälkeen ainoa tuotos oli joku Hello World niin ei oikein jaksanut kiinnostua.
Edit: mulla on Windows-käyttis. kumpi kannattaa asentaa, versio 2.6.2 vai 3.0.1
Tuskinpa eri kielten pitkien lukujen toteutuksissa aivan hirmuisia eroja on, ts. jos jokin tapa olisi järkyttävän paljon parempi kuin muut, olisi outoa, jos sitä ei käytettäisi muissakin kielissä. Usein olennaisempia nopeutuksia saa aikaan valitsemalla muilta osin tehokkaan algoritmin ongelmaan.
Kun kerran uutta kieltä aloittelet, suosittelen uudempaa versiota. Uudempi versio kielestä on luultavasti aina parempi, kukapa sitä huonommaksi tahallaan muuttaisi. Pythonin versioiden välillä on kuitenkin muita olennaisia eroja, joiden takia Python 2 -koodi ei toimi kaikilta osin Python 3:lla. Suuri osa netistä löytyvistä ohjeista on yhä Python 2:lle; kuten versionumeroista näkee, Python 3 julkaistiin vasta vähän aikaa sitten. Ajantasaiseksi oppimateriaaliksi kelpaa ainakin Pythonin dokumentaatio.
Tosiaan tuon kolmosen itsekin valitsisin.
Pythonin virallisilta sivuilta löytyy tietoa, että mitä eroja tuossa kolmosversiossa on versioon 2.6 nähden. http://docs.python.org/3.0/whatsnew/3.0.html kannattanee vilkaista, jos katsot jotain esimerkkejä ja muita koodinpätkiä, jotka on kirjoitettu versiolle 2.6. Hyvässä tutoriaalissa luulisi myös tuotavan näitä eroja esille. Toki välttämätöntä ei ole noita eroja tietää, jos vain uudemman koodin kanssa on tekemisissä.
Ja tuolta http://docs.python.org/3.0/library/2to3.html löytyy ohjelma, joka osaa tarvittaessa muuttaa python kakkosen koodia kolmoselle sopivaksi, jos vaikka tulee vastaan esimerkkejä joita haluat kokeilla, mutta eivät ole python kolmosen mukaisia jostain syystä, niin tuosta voi olla apua.
Kiitos, löytyi näköjään jo versio 3.1 ja latasin juuri. Sitten vaan opiskelemaan.
setä kirjoitti:
Löytyi näköjään jo versio 3.1.
Luultavasti se toimii aivan hyvin, mutta kyseessä on kuitenkin periaatteessa epästabiili kehitysversio (RC, release candidate, julkaisuehdokas).
Pythonissa on valmiina rajattoman pitkät kokonaisluvut. Entä rajattoman pitkät liukuluvut? Onko Pythonissa vai onko joku muu kieli tähän parempi. Jos esim. haluaisin laskea piin desimaaleja 10 000 kpl. niin mikä kieli tähän sopisi parhaiten?
Paras kieli riippuu tietysti aina vähän käyttötarkoituksesta. Vaativaan laskentaan kannataa harkita ohjelmointikielten sijaan laskentaohjelmistoiksi kutsuttavia järjestelmiä. Nämä ovat hyviä varsinkin silloin, jos haluaa itse kokeilla yksinkertaisia ohjelmia, jotka tekevät vaikeita laskuja, tai silloin, jos tosiaan on kiinnostunut lähinnä laskujen tuloksista. Esimerkiksi Mathematicassa piin likiarvo 10000 numeron tarkkuudella saadaan komennolla N[Pi,10000]
. Avoimen lähdekoodin puolelta löytyy esimerkiksi Sage, jonka käyttöliittymäkieli on mukavasti Python (laskut ja skriptit siis kirjoitetaan ohjelmaan Pythoniksi).
Itsenäisissä ohjelmissa vaatimukset ohjelmointikieleltä tai kirjastolta riippuvat paljolti siitä, mitä mielivaltaisella tarkkuudella oikeastaan lasketaan. Nelilaskimen toiminnot on helppo toteuttaa ja ne löytyvät myös valmiina joistakin kielistä (mukaanlukien Python). Vaativammat laskutoimitukset (kuten alkeisfunktiot tai erikoisfunktiot) taas löytyvät tyypillisesti erillisistä laskentakirjastoista.
Lisää tietoa Wikipediassa:
http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic
Kiitos, kiinnostavia linkkejä. Ei vanha tällaisista osannut unelmoidakkaan kun 50 vuotta sitten mekaaninen "piikkisika" oli ihme vekotin kun sillä pystyi erinäisin konstein suorittamaan kerto- ja jakolaskujakin. Kun sitten myöhemmin opintojen jälkeen ilmaantui ensimmäinen funktiolaskin, olikohan tyypiltään HP35, niin sehän se vasta ihmeellinen oli.
Rajattoman pitkä liukuluku kuulostaa jo lähtökohtaisesti hieman hankalalta.
Jos vaikka heittäisi laskun 1/3 niin yhtäkkiä muistia olisi kulunut rajattomasti :D
Toisaalta tuossahan voisi käyttää jaksollisia desimaaliesityksiä...
Vastaus rajattoman pitkiin liukulukuihin on sama kuin rajattoman pitkiin kokonaislukuihin: mikä tahansa kieli. Tai ei oikeastaan mikään. Jos Python ymmärtää "rajattoman" pitkiä kokonaislukuja, niin se on plussaa, sillä niillä voidaan ilmaista "rajattoman" pitkiä liukulukuja, mutta oikeasti rajattoman pitkiä lukuja ei mikään kieli pysty käsittelemään. Koska muisti loppuu. Myös virtuaalimuisti.
Tietokone käsittelee aina rajallisen pituisia lukuja, oli tyyppi mikä tahansa. Pitkän luvun käsittely on helppo toteuttaa millä tahansa kielellä, myös konekielellä. Esim. yhteenlaskuun on olemassa valmiita konekäskyjä, joilla tavun ylivuoto siirretään seuraavaan tavuun. Pitää vain päättää talletustapa, ja toteuttaa laskuoperaatiot sen mukaan.
10000 piin desimaalia ei ole minkään mittapuun mukaan paljon, mutta niiden laskemiseen tarvitaan sopiva algoritmi, jonka voi kyllä toteuttaa ihan millä tahansa olemassa olevalla ohjelmointi-kielellä. Vieläpä ajassa, jossa odottava ihminen ei ehdi edes tajuta, ettei vastaus tullut heti.
Myös tarkkojen n/m arvojen tallettaminen ja niiden väliset laskutoimitukset on helppo toteuttaa millä tahansa kielellä, n,m kokonaislukuja. Millään tavalla ei kuitenkaan ole mahdollista laskea ja ilmaista Piin tarkkaa arvoa numeroina tai yleistä reaalilukua.
Itse olen löytänyt n. 2^2000 suuruisen alkuluvun laitteella, jossa ainoa laskuoperaatio oli yhteenlasku ja muistia oli 16 kilotavua.
Näppäilyvirhe: siis 2^32000.
Joitakin vuosia sitten kehittelin VB 5.0:aan aritmetiikkaohjelmaa, jossa numeroiden määrä oli "rajaton" ja näytettiin merkkijonoina. Hitaaksi se kuitenkin meni ja virheitäkin pukkasi. Nyt käytin desimal-tyyppiä, jolla pääsee 29 numeroon mutta vain normaalit aritmetiikkaoperaatiot toimivat. Hain alkutekijöitä pitkiin lukuihin ja parhaimmillaan aikaa meni minuutteja tai sitten ohjelma sekosi. Olen miettinyt jotain taulukkosysteemiä Long-tyypin luvuilla mutta hankalalta tumtuu. löytyykö tuohon jotain vinkkiä.
Yleisesti ottaen isojen lukujen jakaminen tekijöihinsä on hidasta. Siihenhän asymmetrinen salauskin perustuu.
Mielestäni pitkien kokonaislukujen toteutus käyttäen numerotaulukkoa on todella helppoa, myös VB:llä. Tosin kieltämättä VB:ssä tuottaa ylimääräistä vaivaa se, että siinä ei ole etumerkittömiä lukuja. Toisaalta kaikkein näppärintähän esim. yhteen- ja vähennyslaskujen tekeminen olisi assemblerilla kun voi käyttää suoraan täyspituisia lukuja ja carry flagia.
Jos se kuitenkin tuntuu hankalalta, niin kannattaisiko käyttää jotain valmista kirjastoa?
Mieluitein askartelisin VB:n kanssa ilman valmiita kirjastoja harrastuksena ja dementian torjuntana. Kun sitten pitkän ähellyksen tuloksena saan jonkun laskentaohjelman mielestäni toimimaan suhtkoht nopeastikkin niin joku vääntää saman homman jollain tehokkaammalla kielellä tai sitten paremmalla algoritmilla noin 1000 kertaa nopeammin niin se vähän vanhaa jurppii. Esim. tuo alkutekijöiden haku hoituu todella vikkelään tuolta: http://wims.unice.fr/wims/wims.cgi?session=SL1B7291A8.2& lang=en& module=tool/algebra/factor.en.
Kyseinen sivu väittää olevansa hukassa (toimiva versio), mutta kuten sanoin, niin isojen lukujen jakaminen tekijöihin on hidasta millä vaan tunnetulla menetelmällä. Tuollakaan sivulla ei pysty isoja lukuja jakamaan tekijöihin, kun suoritusaika on rajattu 20 sekuntiin.
Jos olet eri mieltä, niin pari vuotta sitten olisit voinut käydä nappaamassa 80000 dollaria tuolta
Linkki ei näemmä kopioitunut oikein. Toimiikohan tämä?
http://wims.unice.fr/wims/wims.cgi?session=SL1B7291A8.2& lang=en& module=tool/algebra/factor.en
Joo, alkuperäisessä linkissäsi oli ylimääräinen piste lopussa.
Enihuu, kuten tuonne edelliseen kommentoin, niin eihän tuota edes voi käyttää isoihin numeroihin. Tietty softan voi ladata omalle koneelle ja ajaa sitten, mutta aikaa siinä menee.
Muistaakseni Kuthin The art of computer programmisssa käsitellään muistin ja kovalevytilan rajoittaman tarkkuuden aritmetiikkaa. Kyseinen teos on kuitenkin vanha ja ei sisällä esimerkiksi Fürerin algoritmia. Onneksi tekijöihin jakaminen on hankalaa, kun muutoin joutuisi tekemään aika moniin ohjelmiin isoja remontteja, kun salausagoritmit pitäisi vaihtaa turvallisimpiin.
hk kirjoitti:
...
oikeasti rajattoman pitkiä lukuja ei mikään kieli pysty käsittelemään
...
Tietokone käsittelee aina rajallisen pituisia lukuja, oli tyyppi mikä tahansa
...
Millään tavalla ei kuitenkaan ole mahdollista laskea ja ilmaista Piin tarkkaa arvoa numeroina tai yleistä reaalilukua.
Tämä riippuu ihan siitä, millä tavoin ilmaista, esittää tai käsitellä tässä yhteydessä määritellään. Jos vaaditaan, että reaaliluvun kaikki ääretön bittiä tai desimaalia ovat koneen muistissa tai ohjelma tulostaa ne, niin äärettömän tarkkuisen luvun esittäminen ei tietenkään ole mahdollista. Tällainen vaatimus ei toisaalta ole mitenkään perusteltu.
Jos riittäväksi esittämiseksi määritellään se, että ohjelma pystyy tulostamaan mielivaltaisen määrän luvun desimaaleja, mikä ainakin matemaattisessa mielessä kelpaa oikein hyvin, on tilanne aivan toinen. Esimerkiksi aiemmin linkittämässäni Wikipedia-artikkelissa on linkki Common Lispillä (vuonna 1989) kirjoitettuun kirjastoon Computable Real Numbers, joka osaa suorittaa juuri tällä idealla esitettyjen reaalilukujen välisiä laskutoimituksia "äärettömällä tarkkuudella".
Käytännössä kyse on siis symbolisesta laskennasta, jonka avulla tunnetusti voidaan päästä yli monista rajatun tarkkuuden liukulukulaskennan rajoitteista.
Jaska kirjoitti:
Onneksi tekijöihin jakaminen on hankalaa, kun muutoin joutuisi tekemään aika moniin ohjelmiin isoja remontteja, kun salausagoritmit pitäisi vaihtaa turvallisimpiin.
Tai siis nykyään ei tunneta tehokasta tapaa jakaa lukua tekijöihin. Minä en sanoisi "onneksi": matematiikan kehitys on tärkeämpää kuin joidenkin salausalgoritmien toimiminen. Jos toivoo, ettei lukuja opita jakamaan tekijöihin nopeasti, samalla toivoo, ettei kauppamatkustajan ongelmaa ja muita tärkeitä NP-täydellisiä ongelmia opita ratkaisemaan nopeasti.
Itseasissa polynomisessa ajassa suoriutuva algoritmi tekijöiden jakoon tunnetaan, jos sitä nyt voi tehokkaana pitää (NP-ongelmien kohdalla polynomisessa ajassa suoriutuvaa algoritmiä taidetaan pitää tehokkaana). Kyseessä siis Shorin algoritmi (http://en.wikipedia.org/wiki/Shor's_algorithm), joka on tarkoitettu kvanttitietokoneelle. Todellisuudessahan tuosta ei siis vielä kauheasti iloa ole.
Tietenkin tarkoitin rajattomalla mielivaltaisen pitkiä desimaalilukuja. Kukapa nyt tunkisi koneen muistin täyteen päättymättömän luvun desimaaleja vaan tarkoitus on määrittää desimaalien määrä halutun suuruiseksi. En oikein päässyt jyvälle edes kuinka Pythonin Windows-ikkuna avataan kun se ei auennut ohjeiden mukaan. Kokeilemalla sitten löysin jonkun Idle.bat- ja idle.py-tiedostot joilla ikkuna avautui. Tuo Sage vaikuttaa todella mielenkiintoiselta mutta vielä en ole syventynyt aiheeseen. Enkä pythoniinkaan vielä. Hidasta näyttää olevan meikäläisen oppiminen.
Tuo os:n linkki ja Common Lisp vaikuttaa myös kiinnostavalta. olisikohan tuo se jota olen haeskellut?
Aihe on jo aika vanha, joten et voi enää vastata siihen.