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 Mathosztá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 longszá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 inttí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:
Mathmatematikát jelentRoundkereket jelentCeilingmennyezetet jelentFloorpadlót jelent
2. Hogyan épülnek fel a lebegőpontos számok
A típus a és a doublekö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*10308intdoublefloatdouble
Tegyük fel, hogy megvan a szám 123456789, és tároljuk egy doublevá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*108double234567898
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/109109109
| 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.0A 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 cnem 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.0A változó értéke b lesz1.0 |
5. Érdekes tény arrólstrictfp
A Java-nak van egy speciális strictfpkulcsszava ( 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