New to GO- how it handles float precision 0.4 + 0.2 is 0.6

New to GO- how it handles float precision 0.4 + 0.2 = 0.6

I am new to chat and learning as value fact that Go is compiled, no classes, goto (exist).

I am still learning some old school BASIC and QBASIC (as good foundation books on programming) and Python and comparing differences with GO.

1990 QBASIC was dealing with single precision by default unless DIM AS DOUBLE:

print 0.2 + 0.4 gave correct 0.6

Python print(0.2 + 0 .4) gives float with 1 at end not 0.6, neither 0.2 + 0.4 == 0.6 (False)

I am positively surprised that there is good touch with GO on basic libraries gives 0.6

But it is still float64.

Can you let me know please how the library is not triggering floating point error, is there logic build not to show decimal places, if number does not have much decimal.
I am surprised many other languages fail as it was is manageable over 30 years ago. I like fact you can assign precision to var in front so small numbers don’t need to be run with high precision.

package main

import "fmt"

func main() {

fmt.Println(0.2 + 0.4)

fmt.Printf("%T\n", 0.2 + 0.4)

}

On other ascpects
I am comparing the input:

BASIC had numeric variable as default,
Python has string,
GO has scanln() as string

Division /

BASIC 5/2 will give 2.5 as \ was for integer division- most elegant solution

Python 2, 5/2 gives 2 as in GO 2 as integer division
Python 3 5/2 gives correct 2.5 as integer div is now //

I don’t like that GO has / as integer as that is rarely used, the should use \ for integer and / to float but if var is assigned as float in front then is ok and that what matters.

Can you let me know please some other obvious difference compared to Python.
I will buy book for sure, In easy steps as series was good Python and VB.

I will see GO getting adoption and will climb as basic libraries are done by professionals not by amateurs like elsewhere. Fact it can compile and fmt has lot of functions is good. Python you have to import everything, even to deal with time or math.

Thank you

Go’s float32 and float64 types follow IEEE 754, just like many other languages. This means that it will be subject to the same limitations.

package main

import "fmt"

func main() {
	fmt.Printf("%T %T\n", 0.2, 0.2+0.4) // float64 float64

	fmt.Println(0.2 + 0.4)                   // 0.6
	fmt.Println(float32(0.2) + float32(0.4)) // 0.6
	fmt.Println(float64(0.2) + float64(0.4)) // 0.6000000000000001
}

playground

Regarding fmt.Println(0.2 + 0.4), the expression contains only literal constants and as such will be evaluated at compile time rather than runtime.

2 Likes

Thank you for explanation. What I liked about QBASIC that still runs on DosBox on modern Windows, although I have also PC286 (12.5 MHz) and PC386 (40 MHz), it used single by default.
It is computational wasteful for most simply arithmetic’s to run float64 and causes error in Python IDLE shell even if typed without print just 0.2 + 0.4

I am surprise default is float64. I can get that float error still on my PC386 if I declare DIM n AS DOUBLE, but not with default single.
I very much like all the precision choices GO gives, different floats or integer signed and unsigned- toolbox is big, and one can use what it needs.

I understand that the language must comply to that IEEE 754 (I was aware of it), but it is like using 5 kg hammer for nail with double precision (they may call it nowadays bit different to past).
That is for user to learn and hope books explain it well what to use to make code faster.

To summarise fmt.Println(0.2 + 0.4) I understand now this is taken as value not as float
literal constants (google it)

This will create float error if assigned like that with := as runs float64 by default.
If it sees numbers small decimal spaces, cannot logic be made at compiler to treat as float32 at compiler as it cannot mathematically give that long decimal spaces in first time.
Fix that way with float32

package main

import "fmt"

func main() {
	a := 0.2
	b := 0.4
	fmt.Println(a + b) // 0.6000000000000001
}