Kokonaislukuarvot (paitsi char) esitetään tietokoneessa ns. 2-komplementtimuodossa. Laskutoimitusten mahdollisesti aiheuttamaa ns. ylivuotoa tai alivuotoa ei havaita!
Literaalivakiot kirjoitetaan tuttuun tapaan: 1, -54, 0, ...
[Ns. oktaali- ja heksadesimaaliarvoille on oma esitysmuotonsa. On paras olla käyttämättä 'tarpeettomia' etunollia, jos ei erityisesti pidä oktaaliluvuista! Myös long-vakioille on oma esitysmuotonsa: 34L]
Erityyppisten kokonaislukuarvojen sekoittaminen ei aina ole ongelmatonta. Luvussa 3.3 opitaan miten kokonaislukutyyppien arvoja voi muuttaa toisikseen.
Merkkiarvot (char) ovat positiivisia kahden tavun mittaisia kokonaislukuja. Merkit on koodattu Unicode-koodilla, joka sisältää maailman useimpien kirjoitusjärjestelmien kirjain- ja numeromerkit. Esitettävissä ovat esimerkiksi mm. seuraavien kielten merkistö: kreikka, kopti, venäjä, heprea, arabia, devanagari, bengali, gurmukhi, gujarati, tamili, telegu, tai, lao, hiragana, katakana, ...
Merkkivakiot esitetään yksinkertaisissa lainausmerkeissä, esimerkiksi: 'A', 'k', ' ', ';', '#', ... . (Kaksoislainausmerkit on varattu String-tyyppisille vakioille!)
Eräille erikoismerkeille on erityiset ilmaukset:
'\b' backspace '\t' tabulaattori (tab) '\n' rivinvaihto (lf) '\f' sivunvaihto (ff) '\r' telanpalautus (cr) '\"' kaksinkertainen lainausmerkki '\'' yksinkertainen lainausmerkki '\\' takakenoviiva '\ddd' merkki, jonka koodi oktaalilukuna on ddd '\udddd' Unicode-merkki, jonka koodi hekdadesimaali- lukuna on dddd
Huom: Näitä ilmauksia voi käyttää myös String-vakioissa!
Huom: '\u0000' on ns. null-merkki. Jos
se esimerkiksi tulostetaan, mitään ei näy...
Javan liukulukutyypit ovat:
Liukulukuliteraalit ovat muotoa: 3.14, 124., .12, 5.6e3, 0.3E-9, 3e-10, 1.8e+3, ...
Huom: Kaikki liukulukuliteraalit ovat oletusarvoisesti tyyppiä double! Vakion saa float-tyyppiseksi kirjoittamalla sen loppuun kirjaimen f tai F: 3.14f, 124.F, .12F, 5.6e3f, 0.3E-9f, ...
(Javan liukulukuaritmetiikka (lähes!) noudattaa standardia IEEE 754.)
(Liukulukujen arvoalueeseen kuuluvat myös positiivinen ja negatiivinen ääretön ja erityinen NaN-arvo, "not a number". Näiden avulla pidetään mm. huoli siitä, että alilausekkeen laskennassa tullut "huono" arvo tekee koko lausekkeen arvon "huonoksi". Tällä kurssilla ei numeerisen laskennan periaatteita käsitellä!)
Java on ns. vahvasti tyypitetty kieli: lausekkeen tyyppi tiedetään (lähes aina) jo käännösaikana, ns. automaattisia tyyppimuunnoksia (implicit conversion) ei tehdä kuin turvallisissa tapauksissa. Tämä tarkoittaa sitä, ettei kääntäjä salli esimerkiksi double-arvon sijoittamista int-muuttujalle, eikä edes double-vakion "0.0" sijoittamista float-muuttujalle vaikka arvo sinne mahtuisikin! (Tarkempia tietoja löytyy Javan spesifikaatiosta: The Java Language Specification: 5.2 Assignment Conversion)
Sääntöjä:
Esimerkki (nimetään muuttujat vähän erikoisesti alkamaan merkillä "_"):
short _short = -23; int _int = 123; long _long = 121234; char _char = 'q'; float _float = 3.14f; double _double = 121.2311; // sallittuja kiellettyjä _int = _short; _short = _int; _long = _int; _int = _long; _double = _short; _short = _double; _double = _float; _float = _double; _int = _char; _char = _int; _short = _char; _char = _short; _double = _char; _short = 8-0; // kokonaislukulaskutoimitukset tehdään // aina vähintään int-tyyppisinä!!
Kääntäjä antaa seuraavantapaisia ilmoituksia (4. virheellinen tapaus):
Ohjelma.java:12: possible loss of precision found : double required: float _float = _double; ^ 1 error
Eksplisiittinen tyyppimuunnos (cast) ilmaistaan kirjoittamalla arvon saajan tyyppinimi sulkeisiin lausekkeen eteen:
short _short = -23; int _int = 123; long _long = 121234; char _char = 'q'; float _float = 3.14f; double _double = 121.2311; _short = (short)_int; _int = (int)_long; _short = (short)_double; _float = (float)_double; _char = (char)_int; _short = (short)_char; _char = (char)_short; _short = (short)(8-0); _short = (short)(3.14 * 1000.3 - 0.00002); // huom. sulkeet lausekkeen ympärillä!!
Järkevillä tapauksilla on järkevä tulkinta: liukuluku katkaistaan kokonaisluvuksi. Kun double-arvosta tehdään float, esitystarkkuus voi pienetä; sopivankokoinen kokonaisluku voidaan muuttaa char-arvoksi, ... (Tarkemmin asiaa esitellään spesifikaatiossa: 5.1.3 Narrowing Primitive Conversions)
Järjettömissä tapauksissa sattuu järjettömyyksiä, joista ohjelmoija kantaa vastuun!
Huom: boolean-tyyppistä lauseketta ei voi muuntaa numeeriseksi edes eksplisiittisellä tyyppimuunnoksella!
Javassa kokonaislukulaskutoimitusten ns. yli- ja alivuotoja ei havaita Kokonaisluvut toimivat 'modulolaskureiden' tapaan: suurimman arvon seuraaja on pienin arvo! Liukulukutyyppejä on laajennettu arvoilla "positiivinen ääretön", "negatiivinen ääretön" ja "ei luku", ... Myös erimerkkiset nollat ovat esitettävissä. Mutta kuten jo aiemmin todettiin, numeerisen laskennan hienouksia ei tällä kurssilla käsitellä.
Kaikille numeerisille tyypeille on käytössä operaatiot:
+ - * / %
Jos molemmat operandit (so. laskettavat) ovat kokonaislukutyyppisiä, myös laskutoimituksen tulos on on kokonaisluku (aina vain joko int tai long - operandien tyypistä riippuen; jos arvo sijoitetaan byte- tai short-muuttujaan, on tehtävä eksplisiittinen tyyppimuunnos!).
Operaatio "/" tarkoittaa kokonaisjakoa, jos sekä osoittaja että nimittäjä ovat jotain kokonaislukutyyppiä. Aina muulloin kyseessä on liukulukujakolasku.
Operaatio "%" on jäännösjako. Tuloksen etumerkki on sama kuin osoittajan etumerkki, nimittäjän etumerkillä ei ole vaikutusta tuloksen etumerkkiin. Jäännösjaon soveltaminen liukuluvuille on sallittua, mutta ei järkevää! (Ks. spesifikaatio 15.17.3 Remainder Operator %.)
Huom: Jos kahden kokonaislukuarvon jakamisen tuloksena halutaan liukuluku, on se erikseen ilmaistava. Esimerkiksi ohjelma:
public class Aritmetiikkaa { public static void main(String[] args) { int a = 5, b = 2; System.out.println( a/b ); System.out.println( a/b * 1.0 ); System.out.println( 1.0 * a/b ); System.out.println( (float)a/b ); System.out.println( (float)(a/b) ); System.out.println( (a/(float)b) ); } }
tulostaa
2 2.0 2.5 2.5 2.0 2.5
Huom: Operaatio "+" tarkoittaa merkkijonojen katenointia (l. yhteenliittämistä) jos edes toinen 'yhteenlaskettavista' on String-olio (laskenta etenee vasemmalta oikealle). Esimerkki:
int i = 2, j = 5; System.out.println( "Summa on " + i+j ); // tulostaa: Summa on 25 System.out.println( "Summa on " + (i+j) ); // tulostaa: Summa on 7 System.out.println( i+j + " on summa" ); // tulostaa: 7 on summa System.out.println( i+ (j + " on summa") ); // tulostaa: 25 on summa
Luokassa Math on määritelty joukko numeeristen lausekkeiden laskennassa käytettäviä perusfunktioita ja pari vakiota (luokka Math kuuluu pakkaukseen java.lang, joka on ohjelmoijan käytettävissä ilman eri määrittelyitä).
Vakioita:
Math.E // luku e (2.718281828459045) Math.PI // luku pii (3.141592653589793)
Funktioita (monia muitakin on!):
Math.abs // itseisarvo Math.sin Math.cos Math.tan Math.exp Math.log // luonnollinen logaritmi Math.sqrt Math.pow // 1. double potenssiin 2. double Math.round Math.random() // double-pseudosatunnaisluku väliltä [0.0, 1.0) Math.max Math.min
Monet Math-luokan metodit on kuormitettu eri tyyppisille parametreille. API-kuvauksessa on täydellinen luettelo Math-luokan metodeista.
Esimerkki:
for (double d=0.0; d < 2*Math.PI; d+=0.1) System.out.println(Math.sin(d));