Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: Luku X lukujärjestelmästä Y järjestelmään Z

Sivun loppuun

kayttaja-2791 [08.08.2006 23:58:48]

#

Eli kuinkas kyseinen operaatio oikein tapahtuukaan? Eli jos haluan muuttaa vaikka 2-kantaisen luvun "10010001010" 8-kantaiseksi luvuksi? Tietenkin niin ettei sitä 10-kantaa tarvitsisi sotkea operaatioon laisinkaan :)

Tzaeru [09.08.2006 00:01:51]

#

https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=luvut

Haku toimii.. :)

EDIT: hups sori, siellä ei ollutkaan oktaalia vaan heksa vaa :< anteex

kayttaja-2791 [09.08.2006 00:07:32]

#

Ah, ok, kiitos.

Edit:
Eipä vaan eipä tuola ollutkaan sitä tietoa jota hain. Tuola oli vain neuvot kuinka pyöriä kymppikannan ympärillä, mutta ei muuten. Ei se haku taidakaan olla niin kaikkivoipa ;)

FooBat [09.08.2006 00:13:27]

#

Yleisesti tuo taitaa onnistua vain ensin muodostamalla muistiin se luku X, jota merkkijono kuvaa eli käytännössä kertomalla kukin lukualkio sopivalla kantaluvun potenssilla.

Kohdekantaluvun esitys saadaan luvusta käyttäen vuoron perään jakojäännöstä (jolla saa aina viimeisen desimaalin) ja katkaisevaa jakolaskua (jolla siirrytään laskemaan seuraavaa desimaalia).

Kantaluvusta 2 siirtyminen kantalukuun 8 on hiukan erikoistapaus, koska 8 on 2:n potenssi. Niinpä voitkin tehdä kyseisen muunnoksen tarkastelemalla aina 3 bittiä kerralla vähiten merkitsevistä biteistä lähtien. Kun muutat 3 bittisen luvun desimaaliluvuksi saat myös vastaavan 8-kantaisen luvun. Eli

010 010 001 010
  2   2   1   2

Metabolix [09.08.2006 00:42:33]

#

Olkoon järjestelmän kantaluku a. Esimerkiksi luku 342 voitaisiin tällöin esittää näin:

3 * a^2 + 4 * a^1 + 2 * a^0

Jos tämä sattuisi olemaan 8-järjestelmän luku, se muuntuisi kymmenjärjestelmään laskemalla:

3 * 8^2 + 4 * 8^1 + 2 * 8^0
3 * 64 + 4 * 8 + 2 * 1
226 (kymmenjärjestelmässä)

Tuosta sen saa johonkin muuhun järjestelmään aloittamalla ylhäältä alaspäin. Vaikkapa 2-järjestelmään:

226 / 2^8 = 226 / 256 = 0 (kokonaislukuina; jätetään desimaalit pois)
226 / 2^7 = 226 / 128 = 1 -> 226 - 128 = 98
 98 / 2^6 =  98 /  64 = 1 ->  98 -  64 = 34
 34 / 2^5 =  34 /  32 = 1 ->  34 -  32 =  2
  2 / 2^4 =   2 /  16 = 0
  2 / 2^3 =   2 /   8 = 0
  2 / 2^2 =   2 /   4 = 0
  2 / 2^1 =   2 /   2 = 1 ->   2 -   2 =  0
  0 / 2^0 =   0 /   1 = 0

Näin tuli tulokseksi 11100010 binaarijärjestelmässä.

Antti Laaksonen [09.08.2006 00:49:17]

#

Lukua ei tarvitse muuttaa 10-järjestelmään, jos osaa laskea muissa järjestelmissä.

Esim. luvun 1110002 muunto 7-järjestelmään (710 = 1112).

1110002 / 1112 = 10002 jää 02
10002 / 1112 = 12 jää 12
12 / 1112 = 02 jää 12

Kun jakojäännökset luetaan viimeisestä aloittaen, saadaan vastaukseksi:

1110002 = 1107

Tässä on vain sellainen ongelma, että jakolaskut ovat aika vaikeita, kun ei enää ollakaan tutussa 10-järjestelmässä.

Damiqib [09.08.2006 11:42:58]

#

https://www.ohjelmointiputka.net/hak/?kieli=PHP­&nimi=base_convert

Jos tuo vaikka toimisi.

kayttaja-2791 [09.08.2006 12:54:10]

#

Kiitokset Antille. Ja toki muillekin, tästä on hyvät lähtökohdat lähteä kehittämään baseConvert-funktiota (kyllä, varmasti sellaisen joku on jo tehnyt tällekin kielelle). Tarkoitus oli laskeskella noita Rubyllä, joten PHP:n funktio ei tällä kertaa auta.

Merri [09.08.2006 13:40:42]

#

VB:llä tein nopeasti tällaisen yleispätevän funktion:

Option Explicit

Public Function LongToAny(ByVal Value As Long, ByVal System As Byte) As String
    Const NUMBERS As String = "0123456789ABCDEF"
    Dim strOut As String
    If System < 2 Or System > 16 Then Exit Function
    Do While Value > 0
        strOut = Mid$(NUMBERS, Value Mod System + 1, 1) & strOut
        Value = Value \ System
    Loop
    LongToAny = strOut
End Function

Muuttaa annetun luvun merkkijonoksi mihin tahansa lukujärjestelmään binääristä heksaan. Toiminta-aluetta voi lisätä pidentämällä NUMBERS-vakiota lisämerkein. Koodin pitäisi olla tarpeeksi yksinkertainen, jotta sen voi portata nopeasti muillekin kielille :)

Optimoitavaa tuossa sitten on vaikka kuinka, esim. on varmaankin hyvin mahdollista laskea etukäteen kuinka pitkä muuttujasta tulee ja varata tarpeeksi muistia kertaalleen, ettei tarvitse kokoajan muistia varailla uudelleen, kuten tuossa ylläolevassa koodissa. Itselläni ei kuitenkaan ole minkäänlaista tarvetta tälle, joten en tätä tästä eteenpäin kehittele.

kayttaja-2791 [09.08.2006 18:29:37]

#

Hyödytöntä kikkailua tullut värkättyä, mutta laitanpa tänne jos jotakuta kiinnostaa (tai ehkä joku vieläpä hyötyy joskus hakua käytettäessä). Tuo yleismuunnin on vielä vaiheessa, mutta katselin huvikseni Wikipediasta muuta lukujärjestelmiin liittyvää. Törmäsin kaavaan jolla saa laskettua aikas tehokkaasti 8- ja 16-kantaiset luvut 10-kantaiseksi luvuksi:

(((d1 * base + d2) * base + d3) * base + d4)...

Luvussa 1571 d1 on siis 1, d2 on 5, d3 on 7 ja d4 on 1.

Kokeilin tuota piruuttani, ja vertasin sitä tuohon yleisempään laskemiskeinoon, eli tähän:

d1 * base^n + d2 * base^(n-1) + d3 * base^(n-2)...

Missä siis n on d on sama kuin edellisessä, ja n on lukua vastaavan merkkijonon pituus.

Nopeusetu oli merkittävä tuolla ensimmäisellä tavalla, suoritusaika Rubyllä oli vain noin lähes puolet siitä mitä tuolla toisella tavalla laskettuna.

Foobatin mainitsema tapa (erikoistapaus 8 ja 16 kantaisilla luvuilla ja binääriluvuilla käpisteltäessä) näyttäisi myös äärimmäisen tehokkaalta, saa nähdä jaksanko sitäkin kokeilla. Voisi tästä jo siirtyä vähän hyödyllisempiinkin juttuihin välissä ;)

Antti Laaksonen [09.08.2006 18:49:15]

#

Itse asiassa tuo nopeampi laskutapa toimii kaikista lukujärjestelmistä 10-järjestelmään.

Esim. luku 34567 muutetaan 10-järjestelmään:

3*73 + 4*72 + 5*71 + 6*70 = 3*343 + 4*49 + 5*7 + 6 = 1266

((3 * 7 + 4) * 7 + 5) * 7 + 6 = (25 * 7 + 5) * 7 + 6 = 180 * 7 + 6 = 1260 + 6 = 1266

Kaava on helposti johdettavissa tarkastelemalla yhteen laskettavien numeroiden yhteisiä tekijöitä.

kayttaja-2791 [09.08.2006 18:58:32]

#

Niinpäs näyttääkin, käsitin kaiketi en.Wikipedian selotuksen jotenkin väärin. Enkä hoksinut tuota johtamistakaan... Toisaalta tuota toista (hitaampaa) tapaa näkee käytettävän vähän kaikkialla (esimerkiksi OP:n oppaissa ja ohjeissa ;), joten en hoksinut edes ajatella asiaa.

koo [09.08.2006 20:31:31]

#

Tuohan on siis Hornerin menetelmä polynomin laskentaan! Sellainenkin tarina on, että joku yli kymmenen vuotta sitten hyvinkin suositun VAX-prosessoriarkkitehtuurin assemblerissa on ollut ihan oma käskynsä "laske tämän asteen polynomin arvo näillä kertoimilla ja tällä äksän arvolla käyttäen Hornerin menetelmää".

Metabolix [09.08.2006 20:40:23]

#

Sehän on täsmälleen sama kaava hieman erilaisessa muodossa. Aivan kuten x2+x on sama kuin x(x+1)

koo [09.08.2006 21:51:21]

#

Niin, sama polynomihan se siinä on vain esitettynä eri tavoilla, siksi lopputuloskin on sama. Laskentamenetelmien tehokkuudessa vain saattaa olla suuriakin eroja. Taikka sitten tarkkuudessa, sillä esimerkiksi liukulukujen tapauksessa useiden lukujen summa kannattaisi laskea niin päin, että ensin lasketaan pienillä luvuilla ja isot ynnätään vasta viimeiseksi.

Tosin, tässä lukujärjestelmätapauksessa tuo homma toimii kai näin vain kun jostakin n-kantaisesta lukujärjestelmästä ollaan muuttamassa lukua koneen sisäiseen esitystapaan, joka on yleensä 2-järjestelmä. Ja silloinhan tuo menee ihan luonnostaan tällä Hornerin menetelmällä, sillä jos vaikka 7-järjestelmän luku on numerosarja 152643, aloitetaan lopputuloksen kerryttäminen vasemman laidan ykkösestä ja siitähän sitä sitten edetään kertomalla seiskalla ja lisäämällä lukuja niin kauan kuin niitä piisaa. Mutta lopputulos on siis koneen sisäisessä esitysmuodossa, eli jos ulos pitääkin saada luku vaikka 9-järjestelmässä, onkos siihen paljon muuta konstia kuin ruveta sitten ottamaan lopputuloksesta ysin jakojäännöstä ja osamäärää kunnes jaettavaa ei enää ole ja tulostaa lasketut jakojäännökset käänteisessä järjestyksessä?


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta