1. Afrunding af reelle tal
Som vi allerede har diskuteret, når et reelt tal tildeles en intvariabel, 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 longheltal (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 intvariabel, 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 inttype).
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:
Mathbetyder matematikRoundbetyder rundCeilingbetyder loftFloorbetyder gulv
2. Hvordan floating-point tal er opbygget
Typen doublekan 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*10308intdoublefloatdouble
Lad os sige, at vi har tallet 123456789og gemmer det som en doublevariabel. 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*108double234567898
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/109109109
| 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.0Værdien af variablen c vil være 1000000000.0(tallet i b variablen er for lille) |
I ovenstående eksempel, aog cbø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.0Værdien af variablen b vil være1.0 |
5. En interessant kendsgerning vedrstrictfp
Java har et særligt strictfpnø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