1. Valós számok kerekítése
Amint már említettük, ha egy változóhoz valós számot rendelünk int
, azt mindig a legközelebbi kisebb egész számra kerekítjük – a tört részt egyszerűen eldobjuk.
De könnyen elképzelhető egy olyan helyzet, amikor egy tört számot a legközelebbi egész számra kell kerekíteni bármelyik irányba, vagy akár felfelé is. Mit tesz ebben az esetben?
Erre és sok hasonló helyzetre a Java-nak van egy Math
osztálya, amely a round()
, ceil()
, és floor()
metódusokkal rendelkezik.
Math.round()
módszer
A Math.round()
módszer egy számot a legközelebbi egész számra kerekít:
long x = Math.round(real_number)
De van itt még egy árnyalat: ez a metódus egész long
számot ad vissza (nem int
). Mivel a valós számok nagyon nagyok lehetnek, a Java készítői úgy döntöttek, hogy a Java legnagyobb elérhető egész típusát használják: long
.
Ennek megfelelően, ha egy programozó az eredményt egy változóhoz szeretné hozzárendelni int
, akkor kifejezetten jeleznie kell a fordítónak, hogy elfogadja az esetleges adatvesztést (abban az esetben, ha a kapott szám nem fér bele egy int
típusba).
int x = (int) Math.round(real_number)
Példák:
Nyilatkozat | Eredmény |
---|---|
|
|
|
|
|
|
Math.ceil()
módszer
A Math.ceil()
módszer egy számot egész számra kerekít. Íme, példák:
Nyilatkozat | Eredmény |
---|---|
|
|
|
|
|
|
Math.floor()
módszer
A Math.floor()
módszer egy számot egész számra kerekít le . Íme, példák:
Nyilatkozat | Eredmény |
---|---|
|
|
|
|
|
|
Természetesen, ha egy számot egész számra kerekítünk, egyszerűbb egyszerűen egy type cast operátort használni:(int)
Nyilatkozat | Eredmény |
---|---|
|
|
Ha nehéz megjegyezni ezeket a neveket, egy rövid angol lecke segít:
Math
matematikát jelentRound
kereket jelentCeiling
mennyezetet jelentFloor
padlót jelent
2. Hogyan épülnek fel a lebegőpontos számok
A típus a és a double
közötti tartományban tárolhat értékeket . Ez a hatalmas értéktartomány (a típushoz képest) azzal magyarázható, hogy a típus (valamint ) teljesen más belső szerkezettel rendelkezik, mint az egész típusok. Belsőleg a típus két számként kódolja az értékét: az elsőt mantisszának , a másodikat pedig kitevőnek hívják .-1.7*10308
+1.7*10308
int
double
float
double
Tegyük fel, hogy megvan a szám 123456789
, és tároljuk egy double
változót. Amikor ezt megtesszük, a számot a rendszer konvertálja -ra , és belül a típus két számot tárol – és . A szignifikáns ("a szám jelentős része" vagy mantissza) pirossal, míg a kitevő kékkel van kiemelve.1.23456789*108
double
23456789
8
Ez a megközelítés lehetővé teszi nagyon nagy és nagyon kicsi számok tárolását. De mivel a számábrázolás 8 bájtra (64 bitre) korlátozódik, és a bitek egy részét a kitevő tárolására használják (valamint a mantissza előjelét és a kitevő előjelét), a mantissza ábrázolásához rendelkezésre álló maximális számjegyek a 15 .
Ez egy nagyon leegyszerűsített leírása a valós számok szerkezetének.
3. Pontosság elvesztése valós számokkal való munka során
Amikor valós számokkal dolgozik, mindig vegye figyelembe, hogy a valós számok nem pontosak . Mindig előfordulhatnak kerekítési és konverziós hibák , amikor decimálisról binárisra konvertálunk. Ezenkívül a leggyakoribb hibaforrás a pontosság elvesztése , amikor a számokat gyökeresen eltérő skálán adjuk össze/kivonjuk.
Ez utóbbi tény kissé elgondolkodtató a kezdő programozók számára.
Ha kivonunk -ból , akkor azt kapjuk .1/109
109
109
Számok kivonása gyökeresen eltérő skálákon | Magyarázat |
---|---|
|
A második szám rendkívül kicsi , ami miatt a jelentőségét (szürkével kiemelve) figyelmen kívül hagyja. A 15 jelentős számjegy narancssárga színnel van kiemelve. |
Mit ne mondjak, a programozás nem azonos a matematikával.
4. Buktató a valós számok összehasonlításakor
Egy másik veszély leselkedik a programozókra, amikor valós számokat hasonlítanak össze. Valós számokkal való munka során merül fel, mert felhalmozódhatnak a kerekítési hibák. Az eredmény az, hogy vannak olyan helyzetek, amikor a valós számok egyenlőek, de nem. Vagy fordítva: a számok várhatóan eltérőek, de azonosak.
Példa:
Nyilatkozat | Magyarázat |
---|---|
|
A változó értéke a a következő lesz 1000000000.0 A változó értéke c : 1000000000.0 (a b változóban lévő szám túl kicsi) |
A fenti példában a
és c
nem kell egyenlőnek lenniük, de vannak.
Vagy vegyünk egy másik példát:
Nyilatkozat | Magyarázat |
---|---|
|
A változó értéke a lesz 1.0 A változó értéke b lesz1.0 |
5. Érdekes tény arrólstrictfp
A Java-nak van egy speciális strictfp
kulcsszava ( strict f loating p oint ), amely más programozási nyelvekben nem található meg. És tudod miért van rá szükséged? Ez rontja a lebegőpontos számokkal végzett műveletek pontosságát. Íme a történet, hogyan alakult:
GO TO FULL VERSION