Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Generelt

I java opererer vi med seks primitive talltyper med forskjellige egenskaper, som brukes forskjellig deretter. Det er 4 heltalls-typer og 2 flyttalls-typer. Forskjellen på disse innad er antall bit tallet representeres ved, og nøyaktighet av de. De mest brukte typene er int og double. Det er viktig å merke seg at tallene man opererer med i java ikke er ideelle matematiske tall, men er representert med et begrenset antall bit, noe som kan føre med seg uønskede egenskaper.

TypeInnholdDefault-verdiStørrelseVerdiområde
byteHeltall08-128 til 127
shortHeltall016-32,768 til 32,767
intHeltall032-2,147,483,648 til 2,147,483,647
longHeltall064-9,223,372,036,854,775,808 til 9,223,372,036,854,775,807
floatFlyttall0.032+/- 1.4E-45 til +/- 3.4028235E+38
doubleFlyttall0.064+/- 4.9E-324 til +/- 1.7976931348623157E+308

Heltall

Det vil sjeldent være noen noe grunn til å bruke noe annet enn int når man bruker heltall. Det vil i så fall være dersom man har bruk for virkelig store tall (se over), som kan løses med et long. Eller man har strenge krav til minnesparsommelighet og skal ha store mengder heltall i array uten å trenge hele verdiområdet til int. I så fall vil et short, eller byte være en mulighet.
Dersom vi vil konvertere mellom to heltall vil dette gå fint dersom tallet er innenfor verdiområdet til den nye typen. 

 

Code Block
languagejava
titleCorrect casting
int i = 99;
byte b = (byte) i;
 
System.out.println(b);
 
// 99

i er innenfor verdiområdet til byte

 

Code Block
languagejava
titleIncorrect casting
int i = 500;
byte b = (byte) i;
 
System.out.println(b);

// -12  

i er utenfor verdiområdet tilbyte

 

 

Code Block
languagejava
titleHigher #bits
int i = Integer.MAX_VALUE;
long l = i;	

System.out.println(l);
 
// 2147483647

Trenger ikke caste "oppover"

Merk at Wrapperklassene (se lenger ned) gir støtte for konvertering mellom talltypene uten casting

Flyttall

Hva flyttall angår vil det vil sjeldent være grunn til å bruke noe annet enn double. Det som er viktig å bemerke seg er at et flyttall blir mindre og mindre nøyaktig desto større det blir og at man kan oppleve upresise beregninger selv med små verdier. 

 

Code Block
languagejava
titleLoss of precision
double d1 = 0.1;
System.out.println(d1); // 0.1

double d2 = 0.2;
System.out.println(d2); // 0.2
			
System.out.println(d1 + d2); // 0.30000000000000004 

// ??? 


Husk at vi prøver å representere flyttall med et begrenset antall bit, noe som
gir mulighet for feil. Presisjon er nøkkelordet, og som vist ovenfor er ikke denne
alltid helt perfekt. 

 

Code Block
languagejava
titleComparing double
double d1 = 0.1;
double d2 = 0.2;
double d3 = d1 + d2;
System.out.println( d3 == 0.3); // False

Med dette i bakhodet må vi alltid være varsomme når vi sammenligner 
doubleverdier. Ikke bruk ==, men heller en veldig liten epsilonverdi til å
filtrere bort små aritmetiske "feil".

Code Block
languagejava
titleEpsilonvalue
double eps = 0.00001;
 
System.out.println( (d3 - eps < 0.3) && (0.3 < d3 + eps)); // True
 

 

Double tar også tre "merkelige" verdier som er greit å vite om:

NaN: "Not a number", NaN kan tildeles en double dersom vi prøver å utføre operasjoner som ikke lar seg gjøre. Se under, eksempel 1.
Infinity: "Uendelig", Infinity er større enn alle tall, og følger noen enkle regler, eksempel 2.
-Infinity: "Negativ uendelig", -Infinity er mindre en alle tall, og følger de samme reglene som Infinity.

Eksempel 1

Code Block
languagejava
titleNaN-code
double d1 = Math.sqrt(-1); // NaN
 
double inf = Double.POSITIVE_INFINITY;
 
double d2 = inf - inf; // NaN

 

Eksempel 2

Code Block
languagejava
titleInfinity
double pos_inf = Double.POSITIVE_INFINITY; // Infinity
double neg_inf = Double.NEGATIVE_INFINITY; // -Infinity
 
System.out.println(pos_inf - 10); // Infinity
System.out.println(neg_inf - 10); // -Infinity
System.out.println(pos_inf * -1); // -Infinity

 

Wrapper-klassene

De primitive talltypene i java har alle en "wrapper"-klasse. Disse klassene pakker inn den primitive talltypen, og gjør det mulig å representere den som et objekt. Dette gjøres ofte av kompilatoren og kalles da "autoboxing".
I java finnes det en Number-klasse som subklasses av de forskjellige wrapper wrapper-klassene som brukes. Number-klassen er abstrakt og et med de abstrakte metodene byteValue(), shortValue() ... doubleValue() som subklassene implementerer for å kunne konvertere til spesifikke talltyper. Et number-objekt vil alltid være en instans av en av subklassene.

 
Bildet er hentet fra oracle sinde Oracles sider. 

Grunner til å bruke en wrapper-klasse framfor en primitiv type:

  • Dersom vi ønsker å sende en klasse som et argument
  • Bruke konstanter klassen holder, som f.eks. MIN_VALUE/MAX_VALUE for den primitive typen
  • Bruke klassemetoder for å konvertere mellom de forskjellige primitive typene

Under følger en nærmere beskrivelse av de forskjellige tallklassene, verdiområdet deres og nøyaktighet ved beregninger med de.

Byte

Klassen pakker inn et byte.

  • 8-bit heltall
  • Verdiområde: -128 til og med 127

Datatypen byte kan brukes til å erstatte int for å spare minne i veldig store arrays, dersom minnesparsommelighet er viktig. Kan også brukes til å tydeliggjøre koden ved at verdiområdet er begrenset.

Byte-klassen har konstanter for MIN/MAX-verdier og ellers et sett med number-metoder for konvertering og sammenligning. 

Når man utfører divisjon med et byte vil det utføres heltallsdivisjon.
Dersom man ikke ønsker heltallsdivisjonen kan dette lett løses ved å deklarere ett av tallene som en double (se under), eller representere tallet som et number-objekt og bruke metoden doubleValue() på objektet.

 Short

Klassen pakker inn et byte.

  • 16-bit heltall
  • Verdiområde: -32,768 til og med 32,767

Short-klassen har konstanter for MIN/MAX-verdier og ellers et sett med number-metoder for konvertering og sammenligning.

Datatypen short kan brukes på samme måte som et bytebare at et short vil bruke mer minneplass enn et byte. 

Integer

Klassen pakker inn et int.

  • 32-bit heltall
  • Verdiområde: -2,147,483,648 til og med  2,147,483,647

Integer-klassen har konstanter for MIN/MAX-verdier og ellers et sett med number-metoder for konvertering og sammenligning.

Når man ikke har noen spesielle krav til verdiområde eller minnesparsommelighet vil et int veldig ofte være det naturlige valget av datatype for et heltall. Et int vil som regel kunne ta alle nødvendige verdier et program trenger, og dersom man trenger enda større tall, kan man prøve et long. 

Long

Klassen pakker inn et long.

  • 64-bit heltall
  • Verdiområde: -9,223,372,036,854,775,808 til og med 9,223,372,036,854,775,807

Long-klassen har konstanter for MIN/MAX-verdier og ellers et sett med number-metoder for konvertering og sammenligning.

Man bruker en long som datatype når verdiområdet til et int ikke holder.

Float

 

Double


Heltalls-klassene har nyttige metoder og attributter og metoder som MAX_VALUE, MIN_VALUE, toString(), valueOf(). 
I tillegg implementerer alle tallklassene Comparable og dermed metoden compareTo(), slik at tall kan sorteres. 

Man skal ikke bruke tallobjekter ukritisk og det er hovedsaklig tre tilfeller vi tar wrapperklassene til tall i bruk:

  • når en må blande ulike talltyper eller talltyper og andre objekt-typer
  • når en ønsker å bruke Collection-rammeverket sammen med tall (både Collection- og Map-subklasser)
  • når en ønsker å skille mellom ikke-noe-tall (null) og en gyldig tall-verdi

Collections med tall

Når vi ønsker å lagre tall i et Collection-objekt må tallene være objekter, men java har mekanismer som i mange tilfeller gjør dette for oss.
Mer om hvorfor vi initialiserer collections med et klassenavn her.

 

Code Block
languagejava
titleAdding objekt
List<Integer> list = ArrayList<Integer>();


list.add(Integer.valueOf(13)); // valueOf() refererer til et objekt


list.get(0) // En Integer

 

Som nevnt over har java mekanismer som konverterer for oss
dersom det er helt tydelig hvilke verdier og typer som forventes

Code Block
languagejava
titleAuto-converting
list.add(n) // oversettes til
list.add(Integer.valueOf(n)) // og

list.get(i) // oversettes til 
list.get(i).intValue() 

...