Arithmetic avarage with floating point

(Che) #1

Hello, silly question but the following snippet contains an error that I can’t find

var (
        an float64
    	n, avg = 0, 0.

for ; ; n++ {
	fmt.Print("number? ")
	if an == 0. {
	avg += an

if n != 0 {
	fmt.Println(avg / float64(n))

The program output is

number? 5.1
number? 2.1
number? 0

rather than 3.6, why?

(Lutz Horn) #2


(Norbert Melzer) #3

Because of the known imprecision that floats are accomponied with.

If you need precise values, you need a precise type.

There are a lot of blog posts available around this topic, I picked the first three hits on google about “floating point money” (as money is the most common example used as “precise value”):

(* I have not read any one of those recently, they are just the first google hits)

(Che) #4

OK, have you any tips how I should round up the result? Maybe by using the systematic error constant

(Norbert Melzer) #5

You can’t round anything up or down to a value that is not representable.

All links we gave you, tell about the inherint imprecission of floating point computations, and either you are in a field where you can safely allow this imprecissions (eg. computer graphics) or not (eg. money).

(Che) #6

OK I found with Google the following snippet
that resolves the problem
Thank you.

(Norbert Melzer) #7

That will just cause further problems. If you need precision, then use a type that has precision.

If its just for display purpose, then use proper annotations in the call to fmt.Printf.

(Che) #8

OK. I can use fmt.Printf in this case to round up the result or math.big to process input data that has precision as 3.5999999999999996. Right?