58127-1 C-ohjelmointi - syksy 1997 Harjoitustehtävät 2, 3.11. - 9.11. Läsnäolo: 3 tehtävää 1. Kirjoita ohjelma, joka tulostaa alkuluvut väliltä 1-n, missä n luetaan syötteestä. Voit käyttää syötteen lukuun hyväksi kirjan ja luentojen esimerkkejä. Luku on alkuluku, jos se on jaollinen vain itsellään ja ykkösellä. Voit pitää n:aa int-tyyppinä. 2. Kirjoita ohjelma, joka tulostaa syötteen sanojen pituuksien frekvenssit tyyliin "Pituus 1: 50kpl" jne. Voit olettaa, että jokainen rivi päättyy rivinvaihtoon. Sen sijaan rivin maksimipituudelle ei ole tässä tehtävässä ylärajaa. Käytä alustustiedostoa ctype.h hyväksi sanavälien haussa. 3. Kirjoita ohjelma, joka muuttaa syötteessä kontrollimerkit muotoon \koodi, jos kontrollikoodille on olemassa lyhennemuoto (esim. \n eli rivinvaihto on tällainen kontrollikoodi. Jos kontrollikoodille ei ole lyhennemuotoa, tulosta se muodossa \oktaaliluku, esim \033 on ESC. Muut merkit tulostetaan tavalliseen tapaan. Merkki on kontrollimerkki, jos ch < 32, missä ch on luettu merkki. Käytä switch-lausetta tarpeen vaatiessa. Vihje: Merkin oktaaliarvon saat esim. seuraavasti: olkoon ch merkki, jonka oktaaliarvoa etsitään. 1. oktaalinumero on ch/64, 2. oktaalinumero on (ch mod 64)/8, 3. oktaalinumero on ch mod 8. Edellä mod on jakojäännös, esim. 5 mod 2 = 1 4. Kirjoita ohjelma, joka tulostaa syötteen binäärimuodossa. Jokainen luettu merkki tulostuu tällöin jonona nollia ja ykkösiä. Voit olettaa, että jokaisessa merkissä on tasan kahdeksan bittiä. Käytä hyväksi C:n bittitason operaattoreita. Vihje: Tämän ohjelman voi tehdä monella tavalla. Yksinkertaisin tapa tehdä se pyydetyllä tavalla on katsoa aina vähiten merkitsevän bitin tila JA-operaattorilla: ch & 0x1 == 1, jos bitti on ykkönen, muuten ch & 0x1 == 0. Tämän jälkeen oikealle tehtävällä sivuttaissiirrolla voidaan siirtää seuraava bitti käsittelyyn. Kun tämä on tehty kaikille kahdeksalle bitille, pitää vielä kääntää tulos ylösalaisin, sillä muuten ohjelma tulostaa vähiten merkitsevän bitin ensin. 5. Kirjoita ohjelma, joka selvittää kääntäjäsi arvovälit int-tyypille. Esim. char-tyypille väli on yleensä -128 - 127. Vertaa tämän jälkeen tuloksia limits.h:ssa oleviin vakioihin INT_MIN ja INT_MAX. Vakioita saa käyttää hyväksi vain vertailuvaiheessa, ei laskentavaiheessa. Vihje: Saat selville ylä- tai alarajan lisäämällä/vähentämällä muuttujan arvoa sopivasti. Kun yläraja ylittyy (alaraja alittuu), niin seuraava arvo onkin pienempi (suurempi) kuin edellinen. Käytä tätä hyväksi. Tämä ei käy kuitenkaan suoraan ratkaisuksi, sillä esim. int saattaa vaatia yli 2 miljardia iterointia ennen ylärajan löytymistä. 6. Liukuluvuissa epsilonilla merkitään pienintä lukua, jolle 1.0+epsilon != 1.0. Kirjoita ohjelma, joka selvittää kääntäjäsi epsilon-arvon float-tyypille. Tarkista sen jälkeen tulos float.h:ssa olevalla vakiolla FLT_EPSILON. Vakiota saa käyttää hyväksi vain vertailuvaiheessa, ei laskentavaiheessa. Voit käyttää tulostuksessa liukuluvun eksponenttimuotoa: printf("%.5e",100.3) tulostaa 1.00300e2 Vihje: Usein tietokoneet (mm. pentiumit) laskevat liukuluvut sisäisellä tarkkuudella, mikä on suurempi kuin ulkoinen tarkkuus. Näin epsilonin arvosta saattaa tulla pienempi kuin sen todellinen arvo. Voit laskea float-tarkkuudella käyttämällä hyväksi muuttujia. Esim. 1.0f+1e-15 != 1.0f, mutta a = 1.0f+1e-15; a == 1.0f __________________________________________________________________