2.2.4 Kokonaisluvut

Se, miten paljon kullekin muuttujalle varataan tilaa, riippuu käytetystä ohjelmointiympäristöstä. Esimerkiksi, käytettäessä Borland C++-kääntäjää mikrotietokoneessa (joko DOS- tai Windows 3.1x -ympäristöissä) varataan kokonaisluvulle (int) tilaa 16 bittiä (kaksi tavua), joten kokonaislukuun voidaan tällöin tallentaa lukuarvoja väliltä

-215 ... 215-1 eli -32 768 ... 32 767.

Jos tämä lukualue ei riitä, voidaan muuttujan esittelyyn lisätä kokomääre long, jolloin siitä tulee pitkä kokonaisluku (long int). Tällöin tilaa varataan 32 bittiä (4 tavua) ja lukualueen laajuus on

-231 ... 231-1 eli -2 147 483 648 ... 2 147 483 647.

Siten muuttujan esittely

int  ika_vuosissa;

varaa 16 bittiä pitkän muistipaikan, jonka sisältöön voidaan viitata muuttujan nimellä ika_vuosissa. Sen sijaan esittely

long int  ika_vuorokausissa;

varaa 32 bittiä pitkän muistialueen.

Useimmissa Unix-koneissa kokonaislukutyypille int varataan tilaa 32 bittiä (4 tavua).

Tarkastellaan esimerkkiohjelmia INT.CPP ja LONG.CPP.

Esimerkkiohjelmissa on lauseita, joiden muotoa ja käyttöä ei vielä ole opetettu. Älä kuitenkaan anna näiden hämätä itseäsi vaan keskity olennaiseen: kokonaislukumuuttujien ominaisuuksiin.

/* *********************************************************
INT.CPP
  Lukee näppäimistöltä kokonaisluvun ja tulostaa sen
  näytölle.
********************************************************* */

#include <iostream.h>

int main(void)
{
  int luku;

  cout << "Anna luku > ";       // tulostetaan näytölle kehote
  cin >> luku;                  // luetaan luku näppäimistöltä
  cout << "Annoit luvun " << luku << "\n"; // tulostetaan luku

  return 0;
}

Ohjelma tuntuu toimivan mainiosti, kunhan pysytellään sallitulla lukualueella -32 768...32 767. Jos mennään tämän lukualueen ulkopuolelle, ei ohjelma enää tulosta odotettuja vastauksia.

Jos syötteeksi annetaan 33 000, tulostaa ohjelma

Anna luku > 33000
Annoit luvun -32536

ja jos syötteeksi annetaan 1 000 000, saadaan tulostus

Anna luku > 1000000
Annoit luvun 16960

Miksi ohjelma tulostaa väärin?

Luvun 33 000 esitys binäärijärjestelmässä on

1000 0000 1110 1000

joka kahden tavun (16 bittiä) kokonaislukuna tulkittuna on negatiivinen luku (ensimmäinen bitti vasemmalta lukien on 1). Luvun 1 000 000 esitys binäärijärjestelmässä on

1111 0100 0010 0100 0000

josta kokonaisluvun tallennusalueeseen mahtuu vain pätkä

0100 0010 0100 0000

neljän ensimmäisen ykkösbitin hukkuessa taivaan tuuliin.

Näin ollen kone ei tee virhettä, vaikka se ei palautakaan identtisesti käyttäjän antamia lukuja. Se toimii ainoastaan sille mahdollisissa rajoissa. Ohjelman tekijän sitä vastoin tulisi varautua ohjelman rajoituksiin ja esim. ilmoittaa käyttäjälle sallittu lukualue ja tarkistaa syötettyjen lukujen oikeellisuus.

2.2.4.1 Pitkät kokonaisluvut

Vastaava tilanne tulee vastaan pitkien kokonaislukujen kohdalla. Suurin esitettävissä oleva positiivinen luku on 231-1 eli 2 147 483 647.

/* *********************************************************
LONG.CPP
  Lukee näppäimistöltä pitkän kokonaisluvun ja tulostaa sen
  näytölle.
********************************************************* */

#include <iostream.h>

int main(void)
{
  long int luku;

  cout << "Anna luku > ";       // tulostetaan näytölle kehote
  cin >> luku;                  // luetaan luku näppäimistöltä
  cout << "Annoit luvun " << luku << "\n"; // tulostetaan luku

  return 0;
}

Annetaan syötteeksi 2 000 000 000. Ohjelma tulostaa

Anna luku > 2000000000
Annoit luvun 2000000000

Siis toimii.

Annetaan syötteeksi 3 000 000 000. Ohjelma tulostaa

Anna luku > 3000000000
Annoit luvun -1294967296

Tallennettava luku ei mahdu tallennusalueeseen, joten seuraa virhetilanne. Virhe voi ilmetä monin eri tavoin: kun muistiin kirjoitetaan enemmän, kuin siellä on tilaa varattuna tälle kirjoitukselle, menee ylimääräinen osa tallennuksesta johonkin muuhun käyttöön varatulle muistialueelle. Mitä tästä sitten aiheutuu, riippuu täysin toisen tiedon käyttötarkoituksesta, sekä siitä, mitä sinne satuttiin "vahingossa" kirjoittamaan. On kuitenkin selvää, että pilasimme tällä alueella aiemmin olleen tiedon.