1. Afrunding af reelle tal
Som vi allerede har diskuteret, når et reelt tal tildeles en int
variabel, rundes det altid ned til det nærmeste mindre heltal - brøkdelen kasseres simpelthen.
Men det er let at forestille sig en situation, hvor et brøktal skal afrundes til det nærmeste heltal i begge retninger eller endda rundes op. Hvad gør du i dette tilfælde?
Til denne og til mange lignende situationer har Java klassen Math
, som har metoderne round()
, ceil()
, og floor()
.
Math.round()
metode
Metoden Math.round()
afrunder et tal til nærmeste heltal:
long x = Math.round(real_number)
Men der er en anden nuance her: denne metode returnerer et long
heltal (ikke et int
). Fordi reelle tal kan være meget store, besluttede Javas skabere at bruge Javas største tilgængelige heltalstype: long
.
I overensstemmelse hermed, hvis en programmør ønsker at tildele resultatet til en int
variabel, skal hun eksplicit indikere over for compileren, at hun accepterer det mulige tab af data (i tilfælde af at det resulterende tal ikke passer ind i en int
type).
int x = (int) Math.round(real_number)
Eksempler:
Udmelding | Resultat |
---|---|
|
|
|
|
|
|
Math.ceil()
metode
Metoden Math.ceil()
runder et tal op til et heltal. Her er eksempler:
Udmelding | Resultat |
---|---|
|
|
|
|
|
|
Math.floor()
metode
Metoden Math.floor()
runder et tal ned til et heltal. Her er eksempler:
Udmelding | Resultat |
---|---|
|
|
|
|
|
|
Når du runder et tal ned til et heltal, er det selvfølgelig nemmere blot at bruge en type cast-operator:(int)
Udmelding | Resultat |
---|---|
|
|
Hvis du har svært ved at huske disse navne, vil en kort engelsk lektion hjælpe:
Math
betyder matematikRound
betyder rundCeiling
betyder loftFloor
betyder gulv
2. Hvordan floating-point tal er opbygget
Typen double
kan gemme værdier i området fra til . Denne enorme række af værdier (sammenlignet med typen) forklares ved, at typen (såvel som ) har en helt anden intern struktur end heltalstyper. Internt koder typen sin værdi som to tal: det første kaldes mantissen , og det andet kaldes eksponenten .-1.7*10308
+1.7*10308
int
double
float
double
Lad os sige, at vi har tallet 123456789
og gemmer det som en double
variabel. Når vi gør det, konverteres tallet til , og internt gemmer typen to numre - og . Signifikanden ("signifikant del af tallet" eller mantisse) er fremhævet med rødt, mens eksponenten er fremhævet med blåt.1.23456789*108
double
23456789
8
Denne tilgang gør det muligt at lagre både meget store antal og meget små. Men fordi tallets repræsentation er begrænset til 8 bytes (64 bit), og nogle af bitsene bruges til at gemme eksponenten ( såvel som mantissens fortegn og eksponentens fortegn), er de maksimale cifre til rådighed til at repræsentere mantissen er 15 .
Dette er en meget forenklet beskrivelse af, hvordan reelle tal er opbygget.
3. Tab af præcision ved arbejde med reelle tal
Når du arbejder med reelle tal, skal du altid huske på, at reelle tal ikke er nøjagtige . Der kan altid være afrundingsfejl og konverteringsfejl ved konvertering fra decimal til binær. Derudover er den mest almindelige fejlkilde tab af præcision ved addering/fradrag af tal på radikalt forskellige skalaer.
Denne sidste kendsgerning er lidt åndssvag for nybegyndere.
Hvis vi trækker fra , får vi .1/109
109
109
At trække tal fra på radikalt forskellige skalaer | Forklaring |
---|---|
|
Det andet tal er ekstremt lille , hvilket vil medføre, at dets signifikans (fremhævet i gråt) ignoreres. De 15 signifikante cifre er fremhævet med orange. |
Hvad kan vi sige, programmering er ikke det samme som matematik.
4. Faldgrube ved sammenligning af reelle tal
En anden fare ligger på lur for programmører, når de sammenligner reelle tal. Det opstår, når man arbejder med reelle tal, fordi der kan akkumuleres afrundingsfejl. Resultatet er, at der er situationer, hvor reelle tal forventes at være lige store, men det er de ikke. Eller omvendt: tallene forventes at være forskellige, men de er lige store.
Eksempel:
Udmelding | Forklaring |
---|---|
|
Værdien af variablen a vil være 1000000000.0 Værdien af variablen c vil være 1000000000.0 (tallet i b variablen er for lille) |
I ovenstående eksempel, a
og c
bør ikke være ens, men de er.
Eller lad os tage et andet eksempel:
Udmelding | Forklaring |
---|---|
|
Værdien af variablen a vil være 1.0 Værdien af variablen b vil være1.0 |
5. En interessant kendsgerning vedrstrictfp
Java har et særligt strictfp
nøgleord ( strict f loating point ), som ikke findes i andre programmeringssprog. Og ved du hvorfor du har brug for det? Det forværrer nøjagtigheden af operationer med flydende kommatal. Her er historien om, hvordan det blev til:
GO TO FULL VERSION