Sumbevarende afrunding

H. B. Hansen


 


Når man, i administrativ databehandling, trykker en kolonne af flydende tal med en eller anden nøjagtighed (antal trykte decimaler) kommer man ofte ud for at deres trykte sum bliver én eller måske to for stor eller for lille på sidste trykte decimal. Det er irriterende, navnlig hvis man kender summen i forvejen (det er måske procenter der skal summere sig op til 100%). Dette sker fordi de enkelte trykte tal der skal adderes afrundes hver for sig til det ønskede antal decimaler. Hvis fx alle addenderne tilfældigvis skal rundes opad ved trykningen, så kan det ske at den trykte sum, som jo er sammensat af tal der ikke er rundet opad før additionerne, bliver for lille. Der er derfor behov for en afrundingsmetode der har den egenskab at de trykte, afrundede tals sum bliver lig med den trykte, afrundede sum.

Løsningen på dette problem består i at afrunde delsummer af den samlede sum, og trykke forskelle mellem disse afrundede delsummer i stedet for de enkelte afrundede addender. Et eksempel viser princippet. Lad os antage at vi har syv tal der skal trykkes og lægges sammen. Tallene har internt i maskinen 2 decimaler, men man ønsker dem trykt som hele tal (uden decimaler).

Hvis tallene er: 5.49, 6.48, 9.30, 4.45, 7.02, 5.13 og 6.49, så bliver de alle sammen rundet nedad når de trykkes som hele tal, og den "tilsyneladende" sum bliver derfor 42, mens den trykte sum bliver 44 fordi summen af alle tallene med decimaler er 44.36. Vi skal altså konstruere en algoritme der afrunder tallene undervejs således at summen af de trykte tal bliver 44.

Beregningerne kan stilles op i et skema:
 
Tal
Afrundet tal
Delsum
Afrundet delsum
Trykt tal
5.49
5
5.49
5
5
6.48
6
11.97
12
7
9.30
9
21.27
21
9
4.45
4
25.72
26
5
7.02
7
32.74
33
7
5.13
5
37.87
38
5
6.49
6
44.36
44
6
Sum
42
44
44

Tallene i kolonnen "Trykt tal" fremkommer ved at finde forskelle mellem afrundede delsummer: 7 er 12 - 5, 9 er 21 - 12, o.s.v.

Hvis man afrunder til et bestemt antal decimaler (altså ikke hele tal), kan man gange tallene med en passende potens af 10 og derefter udføre afrundingsberegningerne, for så at dividere med potensen ved trykningen.

En algoritme for denne beregning ser således ud (de n tal der skal adderes er indiceret med indeks k):

     tipotens := 10dec
     forrigesum := nysum := reelsum := 0
     loop k := 1 to n
      reelsum := reelsum + xk
      nysum := afrund (reelsum*tipotens) efter 5-reglen
      tryk (nysum - forrigesum)/tipotens
      forrigesum := nysum
     end loop
     tryk nysum/tipotens

Her er et Javaprogram, der demonstrerer denne algoritme. Du kan enten prøve at køre med programmet eller se programteksten.
 



Kildetekst