I Java finnes det situasjoner der man trenger å behandle tall som er for store eller små for de primitive datatypene som double, eller når presisjonen på 15 desimaler som double gir, ikke er tilstrekkelig. For å håndtere slike tall, kan man bruke to spesialiserte klasser fra Java API-en: BigInteger og BigDecimal. Disse klassene gir muligheten til å operere med tall som overskrider grensene for primitive datatyper, og de kan også gi et angitt antall desimaler med presisjon.

Både BigInteger og BigDecimal er immutabel, noe som betyr at objektets verdi ikke kan endres etter at det er opprettet. For å operere på objektene bruker man metoder som er en del av disse klassene. Eksempelvis, for å legge sammen to objekter, kan man bruke metoden add, som returnerer et nytt objekt som inneholder summen av de to. I likhet med primitive datatyper, er det metoder for å utføre alle de vanlige matematiske operasjonene, som modulus, samt metoder som ligner de i Math-klassen, som for eksempel for å finne den største felles divisoren eller generere et primtall.

BigInteger-klassen

En vanlig bruk av BigInteger kan ses i beregningen av Fibonaccifrekvensen. Fibonacci-sekvensen er en rekke der hvert tall er summen av de to forrige. De første to tallene i sekvensen er definert som 1, og alle påfølgende tall beregnes på samme måte: fn = fn-2 + fn-1. Når vi kommer til det 93. tallet i sekvensen (f93), blir verdiene større enn hva den primitive typen long kan håndtere. Her kan BigInteger benyttes til å håndtere tall som overskrider størrelsen på long.

En enkel applikasjon som beregner Fibonacci-sekvensens elementer demonstrerer hvordan man bruker BigInteger for slike beregninger. Programmet oppretter instanser av BigInteger for å beregne og skrive ut ønsket Fibonacci-verdi. Ved å bruke metoden add kan man summere de to siste tallene i sekvensen for å beregne det neste, og bruke toString for å konvertere objektet til en streng for utskrift. Programmet sammenligner deretter verdiene med maksverdien for long ved hjelp av metoden compareTo, som returnerer et heltall som indikerer om verdien er større enn den primitive typen.

BigDecimal-klassen

BigDecimal brukes når man trenger å håndtere reelle tall med høy presisjon. Dette kan for eksempel være nødvendig ved beregning av verdier som involverer deling, der man ønsker å kontrollere antall desimaler. BigDecimal kan for eksempel brukes til å dele 176 med 7 og deretter kontrollere presisjonen til resultatet, for eksempel 19, 18, 17 eller 16 desimaler. Denne kontrollen over presisjonen oppnås ved hjelp av metoden divide, som tar tre argumenter: det første er objektet som skal deles, det andre spesifiserer presisjonen, og det tredje angir hvilken avrundingsmetode som skal brukes.

For avrunding finnes det flere metoder i BigDecimal, og en vanlig metode er HALF_UP, som avrunder verdien oppover dersom det er en 5 i det siste desimalet. Metoden divide gir deg muligheten til å håndtere både nøyaktighet og avrunding på en fleksibel måte, noe som er svært viktig når du jobber med finansielle applikasjoner eller vitenskapelige beregninger som krever høy presisjon.

Viktigheten av å forstå store tall og presisjon

Når man arbeider med store tall eller tall som krever mer presisjon enn det som tilbys av primitive datatyper som double, er det viktig å forstå både de praktiske anvendelsene og de potensielle utfordringene som kan oppstå. Bruken av BigInteger og BigDecimal gir programmørene fleksibiliteten til å håndtere tall som er mye større enn standard datatyper tillater, men samtidig kan det også medføre ytelsesmessige utfordringer. Siden objektene i disse klassene er immutabel, kan operasjonene som utføres på dem føre til opprettelse av nye objekter, noe som kan være mer ressurskrevende enn operasjoner på primitive datatyper.

I tillegg er det viktig å merke seg at BigInteger og BigDecimal ikke er ment for alle typer applikasjoner. Hvis man kun trenger et begrenset antall desimaler eller mindre tall, kan bruken av disse klassene være unødvendig og føre til ineffektiv kode. Derfor bør programmerere nøye vurdere når det er hensiktsmessig å bruke disse klassene for å sikre både korrekthet og optimal ytelse.

Hvordan bestemme hvor mye "lommepenger" du har etter regningene?

I en typisk samtale mellom en person og en rådgiver som prøver å hjelpe med økonomisk planlegging, kan man enkelt definere to hovedmål: beregne hvor mye penger en person har igjen til "mad money" etter å ha betalt sine faste månedlige regninger, og finne ut hvor stor prosentandel av inntekten som går til hver av de fem faste utgiftene.

La oss ta et konkret eksempel. I samtalen mellom Annie og en annen person, fremkommer et ønske om å få kontroll på økonomien. Annie arbeider på provisjon, noe som betyr at inntekten hennes varierer fra måned til måned. De fem faste utgiftene er mat, husleie, strøm, telefon og klær. Annie ønsker å forstå hvor mye penger hun bruker på hver av disse utgiftene og hva som blir igjen som "mad money", altså penger hun kan bruke på hva hun vil uten å være bundet av faste regninger.

For å oppnå dette, må Annie legge inn de månedlige beløpene for hver av regningene og den totale inntekten hennes for måneden. Ved hjelp av et program kan man da regne ut hvor mye penger hun har igjen etter regningene (mad money), samt beregne prosentandelen som går til de ulike kategoriene av utgifter. Denne informasjonen vil hjelpe Annie med å få oversikt over hvordan pengene hennes fordeles, og om hun bruker mer enn hun bør på for eksempel klær eller mat.

For programmereren som utvikler et slikt system, er det viktig å forstå hvilke spesifikasjoner og funksjoner brukeren, som Annie, ønsker. Spesifikasjonen for et slikt program er ganske enkel: det må ta inn fem ulike regningsbeløp og en inntekt, deretter beregne hva som er igjen og hvor mye som går til hver kategori, og til slutt lagre resultatene for fremtidig sammenligning. Det kan også være nyttig å legge til muligheten for å lagre resultatene per måned og år for å spore økonomiske endringer over tid. Dette kan være en praktisk funksjon for å hjelpe Annie (eller en annen bruker) med å analysere økonomiske mønstre.

Denne tilnærmingen til økonomisk planlegging kan overføres til mange andre situasjoner. For eksempel kan et spill, som i eksemplet med Ryan som ønsker å lage et spill kalt "Deep Space Delivery", også spesifiseres på en lignende måte. Spilldesignere bruker spesifikasjoner for å definere spillets mål, objekter og mekanikk, før de begynner programmeringen. Dette er et viktig steg i å utvikle både programmer og spill, da det skaper klare rammer for hva som skal oppnås, og hvordan det skal gjøres.

I begge tilfeller – enten det er et økonomisk program eller et spill – er prosessen med spesifikasjon en viktig del av utviklingen. Når systemet er spesifisert, kan programmereren gå videre med å implementere løsningen. I Annie’s tilfelle ville programmet lage et regnskap for hennes inntekter og utgifter, og gi henne en oversikt som hjelper henne med å ta informerte økonomiske beslutninger.

En viktig faktor som ofte overses i slike programmer, er muligheten for å forbedre programmet gjennom tilbakemeldinger. Etter at en første versjon er skrevet, kan det vise seg at ytterligere funksjoner kan legges til. For eksempel kan Annie ønske å ha en funksjon som gir en advarsel når hun bruker en uforholdsmessig stor andel av inntekten på en bestemt kategori. Dette vil gi henne muligheten til å tilpasse forbruket sitt og potensielt frigjøre mer penger til det hun kaller "mad money".

En annen viktig hensikt med programmet kan være å analysere om forbruket er bærekraftig over tid. For eksempel, hvis Annie legger merke til at matutgiftene hennes øker dramatisk hver måned, kan hun sette inn tiltak for å redusere disse kostnadene. Økonomisk bevissthet kan bidra til en mer balansert økonomi, der det er mer plass til fleksibilitet og spontanitet, som kan være en viktig del av livet.