Viime osan lopuksi vihjasin, että ympäripyörähtävät luvut käyttäytyvät hyvin kummallisesti. Auton matkamittari pyörähtää miljoonan kilometrin sijaan nollaksi, mutta sen ei odoteta pystyvän esittämään negatiivisia kilometrejä. Tietokoneessa miinusmerkit ovat kuitenkin välttämättömiä, ja siksi $127+1$ voikin olla $-128$!
Käänteistä logiikkaa
Millä tavalla negatiiviset luvut kannattaisi esittää? Yksi idea olisi varata luvusta yksi bitti etumerkille. Voitaisiin vaikka sopia, että luku on negatiivinen, jos sen vasemmanpuoleisin bitti on ykkönen. Tässä kohtaa on olennaista, että lukujen pituus on rajoitettu — muuten "vasemmanpuoleisin" olisi huonosti määritelty. Käytän tässä tekstissä 8-bittisiä lukuja, jolloin $+1 = 00000001$.
Tässä esitystavassa $10000001$ olisi yhtä kuin $-1$. Tämä on hyvä idea, ja sitä on käytetty joissakin tietokoneissa historian varrella. Kummallisena piirteenä luvut $+0$ ja $-0$ ovat erillisiä! Toinen menetelmä, jolla on sama ominaisuus, on jokaisen bitin kääntäminen: tällöin $11111110 = -1$. Kummassakin tavassa etumerkki pitää ottaa huomioon yhteenlaskussa.
Oikeasta lähestymistavasta käytiin kiivasta keskustelua tietotekniikan alkuaikoina 50-60-luvuilla. Lopulta voittajaksi nousi vaihtoehto, joka oli helppo toteuttaa laitteistossa. Kahden komplementti on menetelmä, jossa lukuja käsitellään täsmälleen samalla tavalla riippumatta niiden merkistä. Myöskin nolla on yksikäsitteinen tässä esitystavassa.
Luku muutetaan negatiiviseksi kääntämällä kaikki sen bitit ja lisäämällä tulokseen yksi. Esimerkiksi $00010010$ (eli $18$) kääntyy muotoon $11101101$, joka lasketaan ykkösen kanssa yhteen: $11101110$. Merkittävää on se, että yhteenlaskussa ei tarvitse välittää etumerkistä, joten viimekertaista logiikkaa ei tarvitse muuttaa. Jää ohjelmoijan tehtäväksi valita, tulkitaanko luvut etumerkillisinä vai aina ei-negatiivisina viime kerran tapaan, jolloin isoin mahdollinen luku kaksinkertaistuu.
Yhteistä muiden menetelmien kanssa on se, että tässäkin esityksessä vasemmanpuoleisin bitti määrää merkin. Tästä seuraa, että 8 bitillä voidaan esittää 128 negatiivista lukua, nolla ja 127 positiivista lukua. Nämä luvut muodostavat suljetun silmukan, jossa luvun $127$ jälkeen tulee $-128$. Kahdella tavulla tämä laajenee väliksi $-32768\dots 32767$ ja niin edelleen.
Ympäripyörähtäminen ei ole aina toivottua, koska se voi käsittelemättömänä aiheuttaa jopa tietoturva-ongelmia. Yksi laajimmista ongelmista liittyy aikaan. Osa tietokoneista ja puhelimista tallentaa kellonajan sekunteina 1.1.1970 alkaen. Tähän käytetään 32-bittistä etumerkillistä lukua, joka oli 70-luvulla järkevä valinta. Ikävä kyllä siitä on nyt tullut ongelma, koska 19.1.2038 kello pyörähtää ympäri joulukuuhun 1901! (Korjaus on isompiin lukuihin siirtyminen, mutta virheellisiä järjestelmiä on vielä paljon.)
Keskenään verrattavia
Vähennyslasku saadaan kasattua yhteenlaskusta, jossa toisesta luvusta on otettu vastaluku. Vähennyslaskusta voidaan puolestaan johtaa kahden luvun vertailu keskenään. Vertailussa on kolme mahdollista tilannetta:
\[ \begin{align*} a &< b \\ a &= b \\ a &> b \end{align*} \]Nämä voidaan kirjoittaa uudelleen muotoon
\[ \begin{align*} a - b &< 0 \\ a - b &= 0 \\ a - b &> 0 \end{align*} \]Koska negatiivisten lukujen vasen bitti on aina 1, ensimmäinen tapaus on yksinkertaisesti sen tarkastaminen. Erotuksen vertaaminen nollaan voidaan toteuttaa vaikkapa TAI-operaatiolla kaikista tuloksen biteistä. Jos kumpikaan näistä ei toteudu, kyseessä on viimeinen tapaus.
Mitä tällä vertailulla sitten tehdään? Siihen syvennymme ensi viikolla, heti maanantaista alkaen!
Kokeiltavaksi ja pohdittavaksi
- Muunna luvut $17$ ja $-17$ kahdeksanbittisiksi binääriluvuiksi. Laske ne yhteen allekkain.
- Avaruusluotain Deep Impact menetettiin (vasta tehtävänsä jälkeen), kun sen sisäinen kello pyörähti ympäri. Kello mittasi aikaa kymmenesosasekunteina 1.1.2000 alkaen, ja se talletettiin 32-bittiseen etumerkittömään lukuun. Minä vuonna luotain hajosi?
Ei kommentteja:
Lähetä kommentti
Kommentit ovat moderoituja — yritän hyväksyä kommenttisi mahdollisimman pian. Voit kirjoittaa kommenttiin LaTeX-koodia tai yksinkertaista HTML-merkintää: lue lisää Kommentointi-sivulta.