1. Avrunding av reelle tall
Som vi allerede har diskutert, når et reelt tall er tilordnet en int
variabel, rundes det alltid ned til nærmeste mindre heltall - brøkdelen blir ganske enkelt forkastet.
Men det er lett å forestille seg en situasjon der et brøktall må rundes av til nærmeste heltall i begge retninger eller til og med rundes opp. Hva gjør du i dette tilfellet?
For denne og for mange lignende situasjoner har Java klassen Math
, som har metodene round()
, ceil()
, og floor()
.
Math.round()
metode
Metoden Math.round()
runder av et tall til nærmeste heltall:
long x = Math.round(real_number)
Men det er en annen nyanse her: denne metoden returnerer et long
heltall (ikke et int
). Fordi reelle tall kan være veldig store, bestemte Javas skapere å bruke Javas største tilgjengelige heltallstype: long
.
Følgelig, hvis en programmerer ønsker å tilordne resultatet til en int
variabel, må hun eksplisitt indikere til kompilatoren at hun aksepterer mulig tap av data (i tilfelle at det resulterende tallet ikke passer inn i en int
type).
int x = (int) Math.round(real_number)
Eksempler:
Uttalelse | Resultat |
---|---|
|
|
|
|
|
|
Math.ceil()
metode
Metoden Math.ceil()
runder et tall opp til et heltall. Her er eksempler:
Uttalelse | Resultat |
---|---|
|
|
|
|
|
|
Math.floor()
metode
Metoden Math.floor()
runder et tall ned til et heltall. Her er eksempler:
Uttalelse | Resultat |
---|---|
|
|
|
|
|
|
Selvfølgelig, når du runder et tall ned til et heltall, er det lettere å bare bruke en type cast-operator:(int)
Uttalelse | Resultat |
---|---|
|
|
Hvis du synes det er vanskelig å huske disse navnene, vil en kort engelsk leksjon hjelpe:
Math
betyr matematikkRound
betyr rundeCeiling
betyr takFloor
betyr gulv
2. Hvordan flyttetallene er bygget opp
Typen double
kan lagre verdier i området fra til . Dette enorme spekteret av verdier (sammenlignet med typen) forklares av det faktum at typen (samt ) har en helt annen intern struktur enn heltallstyper. Internt koder typen verdien som to tall: det første kalles mantissen , og det andre kalles eksponenten .-1.7*10308
+1.7*10308
int
double
float
double
La oss si at vi har tallet 123456789
og lagrer det som en double
variabel. Når vi gjør det, konverteres tallet til , og internt lagrer typen to tall - og . Signifikanden («signifikant del av tallet» eller mantissa) er uthevet i rødt, mens eksponenten er uthevet i blått.1.23456789*108
double
23456789
8
Denne tilnærmingen gjør det mulig å lagre både svært store og svært små. Men fordi tallets representasjon er begrenset til 8 byte (64 biter) og noen av bitene brukes til å lagre eksponenten ( så vel som tegnet på mantissen og tegnet til eksponenten), er de maksimale sifrene tilgjengelig for å representere mantissen er 15 .
Dette er en veldig forenklet beskrivelse av hvordan reelle tall er bygget opp.
3. Tap av presisjon ved arbeid med reelle tall
Når du arbeider med reelle tall, husk alltid at reelle tall ikke er eksakte . Det kan alltid være avrundingsfeil og konverteringsfeil ved konvertering fra desimal til binær. I tillegg er den vanligste feilkilden tap av presisjon når man adderer/subtraherer tall på radikalt forskjellige skalaer.
Dette siste faktum er litt oppsiktsvekkende for nybegynnere programmerere.
Hvis vi trekker fra , får vi .1/109
109
109
Å trekke fra tall på radikalt forskjellige skalaer | Forklaring |
---|---|
|
Det andre tallet er ekstremt lite , noe som vil føre til at dets signifikans (uthevet i grått) blir ignorert. De 15 signifikante sifrene er uthevet i oransje. |
Hva kan vi si, programmering er ikke det samme som matematikk.
4. Fallgruve ved sammenligning av reelle tall
En annen fare ligger på lur for programmerere når de sammenligner reelle tall. Det oppstår når man jobber med reelle tall, fordi avrundingsfeil kan hope seg opp. Resultatet er at det er situasjoner der reelle tall forventes å være like, men det er de ikke. Eller omvendt: tallene forventes å være forskjellige, men de er like.
Eksempel:
Uttalelse | Forklaring |
---|---|
|
Verdien av variabelen a vil være 1000000000.0 Verdien av variabelen c vil være 1000000000.0 (tallet i b variabelen er for lite) |
I eksemplet ovenfor, a
og c
bør ikke være like, men de er.
Eller la oss ta et annet eksempel:
Uttalelse | Forklaring |
---|---|
|
Verdien av variabelen a vil være 1.0 Verdien av variabelen b vil være1.0 |
5. Et interessant faktum omstrictfp
Java har et spesielt nøkkelordstrictfp
( strict f loating point ), som ikke finnes i andre programmeringsspråk. Og vet du hvorfor du trenger det? Det forverrer nøyaktigheten av operasjoner med flyttall. Her er historien om hvordan det ble til:
GO TO FULL VERSION