The Go Programming Language Specification

Integer literals

An integer literal is a sequence of digits representing an integer constant.

Floating-point literals

A floating-point literal is a decimal representation of a floating-point constant. It has an integer part, a decimal point, a fractional part, and an exponent part. The integer and fractional part comprise decimal digits; the exponent part is an e or E followed by an optionally signed decimal exponent. One of the integer part or the fractional part may be elided; one of the decimal point or the exponent may be elided.

Arithmetic operators

For two integer values x and y, the integer quotient q = x / y and remainder r = x % y satisfy the following relationships:

x = q*y + r  and  |r| < |y|

with x / y truncated towards zero.


You wrote, using integer literals and arithmetic (x / y truncates towards zero):

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var num float64
    num = 5 / 3 // float64(int(5)/int(3))
    fmt.Printf("%v\n", num)
    numString := strconv.FormatFloat(num, 'f', -1, 64)
    fmt.Println(numString)
}

Playground: https://play.golang.org/p/PBqSbpHvuSL

Output:

1
1

You should write, using floating-point literals and arithmetic:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var num float64
    num = 5.0 / 3.0 // float64(float64(5.0) / float64 (3.0))
    fmt.Printf("%v\n", num)
    numString := strconv.FormatFloat(num, 'f', -1, 64)
    fmt.Println(numString)
}

Playground: https://play.golang.org/p/Hp1nac358HK

Output:

1.6666666666666667
1.6666666666666667
Answer from peterSO on Stack Overflow
🌐
Reddit
reddit.com › r/golang › what the heck with float64?
r/golang on Reddit: What the heck with float64?
March 8, 2024 -

I know javascript has problems when number goes big, usual thing is that trailing digits will be truncated to zero. And I wonder what that looks like in golang, so I write a program:

see https://go.dev/play/p/2rbKFNiupQ_6

package main

import "fmt"

func main() {
    var v1 float64 = 1876219900889841660
    var v2 float64 = 1876219900889841661
    var v3 float64 = 1876219900889841662
    var v4 float64 = 1876219900889841663
    var v5 float64 = 1876219900889841664
    var v6 float64 = 1876219900889841665
    var v7 float64 = 1876219900889841666
    var v8 float64 = 1876219900889841667
    var v9 float64 = 1876219900889841668
    fmt.Printf("v1==v2: %v\n", v1 == v2)      // true
    fmt.Printf("v2==v3: %v\n", v2 == v3)      // true
    fmt.Printf("v3==v4: %v\n", v3 == v4)      // true
    fmt.Printf("v4==v5: %v\n", v4 == v5)      // true
    fmt.Printf("v5==v6: %v\n", v5 == v6)      // true
    fmt.Printf("v6==v7: %v\n", v6 == v7)      // true
    fmt.Printf("v7==v8: %v\n", v7 == v8)      // true
    fmt.Printf("v8==v9: %v\n", v8 == v9)      // true
    fmt.Printf("int64(v4): %d\n", int64(v4))  // 1876219900889841664
    fmt.Printf("int64(v9): %d\n", int64(v9))  // 1876219900889841664
    fmt.Printf("float64(v9): %.0f\n", v9)     // 1876219900889841664
}

Why all float64 numbers are printed as 1876219900889841664? In javascript this is 1876219900889841700. Anyone can give an explanation please? Thanks.

Discussions

go - Float64 type printing as int in Golang - Stack Overflow
Surprisingly I couldn't find anyone else having this same issue; I tried simply initializing a float64 in Go and printing it, then attempting a string conversion and printing that. Neither output was More on stackoverflow.com
🌐 stackoverflow.com
Convert a float64 to an int in Go - Stack Overflow
How does one convert a float64 to an int in Go? I know the strconv package can be used to convert anything to or from a string, but not between data types where one isn't a string. I know I can use... More on stackoverflow.com
🌐 stackoverflow.com
math/big: add Int.Float64 conversion (was initially: {ToInt64,ToUint64,Float64})
The Int type in the math/big package represents an arbitrary-precision integer. Today, it provides methods called Int64 and Uint64, which return the integer in the int64 and uint64 (machine) repres... More on github.com
🌐 github.com
17
November 29, 2022
go - Golang floating point precision float32 vs float64 - Stack Overflow
I wrote a program to demonstrate floating point error in Go: func main() { a := float64(0.2) a += 0.1 a -= 0.3 var i int for i = 0; a More on stackoverflow.com
🌐 stackoverflow.com
🌐
Educative
educative.io › answers › what-is-type-float64-in-golang
What is type float64 in Golang?
A variable of type float64 can store decimal numbers ranging from 2.2E-308 to 1.7E+308.
🌐
Go
go.dev › src › math › big › float.go
- The Go Programming Language
551 func (z *Float) SetFloat64(x float64) *Float { 552 if z.prec == 0 { 553 z.prec = 53 554 } 555 if math.IsNaN(x) { 556 panic(ErrNaN{"Float.SetFloat64(NaN)"}) 557 } 558 z.acc = Exact 559 z.neg = math.Signbit(x) // handle -0, -Inf correctly 560 if x == 0 { 561 z.form = zero 562 return z 563 } 564 if math.IsInf(x, 0) { 565 z.form = inf 566 return z 567 } 568 // normalized x != 0 569 z.form = finite 570 fmant, exp := math.Frexp(x) // get normalized mantissa 571 z.mant = z.mant.setUint64(1<<63 | math.Float64bits(fmant)<<11) 572 z.exp = int32(exp) // always fits 573 if z.prec < 53 { 574 z.round(0) 575 } 576 return z 577 } 578 579 // fnorm normalizes mantissa m by shifting it to the left 580 // such that the msb of the most-significant word (msw) is 1.
Top answer
1 of 1
4

The Go Programming Language Specification

Integer literals

An integer literal is a sequence of digits representing an integer constant.

Floating-point literals

A floating-point literal is a decimal representation of a floating-point constant. It has an integer part, a decimal point, a fractional part, and an exponent part. The integer and fractional part comprise decimal digits; the exponent part is an e or E followed by an optionally signed decimal exponent. One of the integer part or the fractional part may be elided; one of the decimal point or the exponent may be elided.

Arithmetic operators

For two integer values x and y, the integer quotient q = x / y and remainder r = x % y satisfy the following relationships:

x = q*y + r  and  |r| < |y|

with x / y truncated towards zero.


You wrote, using integer literals and arithmetic (x / y truncates towards zero):

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var num float64
    num = 5 / 3 // float64(int(5)/int(3))
    fmt.Printf("%v\n", num)
    numString := strconv.FormatFloat(num, 'f', -1, 64)
    fmt.Println(numString)
}

Playground: https://play.golang.org/p/PBqSbpHvuSL

Output:

1
1

You should write, using floating-point literals and arithmetic:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var num float64
    num = 5.0 / 3.0 // float64(float64(5.0) / float64 (3.0))
    fmt.Printf("%v\n", num)
    numString := strconv.FormatFloat(num, 'f', -1, 64)
    fmt.Println(numString)
}

Playground: https://play.golang.org/p/Hp1nac358HK

Output:

1.6666666666666667
1.6666666666666667
🌐
Medium
medium.com › techtrends-digest › golang-why-float64-betrays-you-and-when-to-use-decimal-instead-41194e13601a
Golang: Why float64 Betrays You and When to Use Decimal Instead
December 2, 2025 - float64 uses binary floating-point representation. Many decimal values can't be represented exactly in binary.
🌐
GitHub
github.com › golang › go › issues › 56984
math/big: add Int.Float64 conversion (was initially: {ToInt64,ToUint64,Float64}) · Issue #56984 · golang/go
November 29, 2022 - I propose to add three new methods to the package: Int.{ToInt64,ToUint64,Float64}. All three follow the same pattern of returning the closest representable value, and a big.Accuracy enum indicating whether the conversion was exact, a rounding up, or a rounding down.
Author   adonovan
Find elsewhere
🌐
YourBasic
yourbasic.org › golang › round-float-2-decimal-places
Round float to 2 decimal places · YourBasic Go
Round float to integer value has further details on how to round a float64 to an integer (away from zero, to even number, converted to an int type).
🌐
YourBasic
yourbasic.org › golang › convert-string-to-float
Convert between float and string · YourBasic Go
Use the strconv.ParseFloat function to parse a string as a floating-point number with the precision specified by bitSize: 32 for float32, or 64 for float64.
Top answer
1 of 2
36

Using math.Float32bits and math.Float64bits, you can see how Go represents the different decimal values as a IEEE 754 binary value:

Playground: https://play.golang.org/p/ZqzdCZLfvC

Result:

float32(0.1): 00111101110011001100110011001101
float32(0.2): 00111110010011001100110011001101
float32(0.3): 00111110100110011001100110011010
float64(0.1): 0011111110111001100110011001100110011001100110011001100110011010
float64(0.2): 0011111111001001100110011001100110011001100110011001100110011010
float64(0.3): 0011111111010011001100110011001100110011001100110011001100110011

If you convert these binary representation to decimal values and do your loop, you can see that for float32, the initial value of a will be:

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9

a negative value that can never never sum up to 1.

So, why does C behave different?

If you look at the binary pattern (and know slightly about how to represent binary values), you can see that Go rounds the last bit while I assume C just crops it instead.

So, in a sense, while neither Go nor C can represent 0.1 exactly in a float, Go uses the value closest to 0.1:

Go:   00111101110011001100110011001101 => 0.10000000149011612
C(?): 00111101110011001100110011001100 => 0.09999999403953552

Edit:

I posted a question about how C handles float constants, and from the answer it seems that any implementation of the C standard is allowed to do either. The implementation you tried it with just did it differently than Go.

2 of 2
18

Agree with ANisus, go is doing the right thing. Concerning C, I'm not convinced by his guess.

The C standard does not dictate, but most implementations of libc will convert the decimal representation to nearest float (at least to comply with IEEE-754 2008 or ISO 10967), so I don't think this is the most probable explanation.

There are several reasons why the C program behavior might differ... Especially, some intermediate computations might be performed with excess precision (double or long double).

The most probable thing I can think of, is if ever you wrote 0.1 instead of 0.1f in C.
In which case, you might have cause excess precision in initialization
(you sum float a+double 0.1 => the float is converted to double, then result is converted back to float)

If I emulate these operations

float32(float32(float32(0.2) + float64(0.1)) - float64(0.3))

Then I find something near 1.1920929e-8f

After 27 iterations, this sums to 1.6f

🌐
Educative
educative.io › answers › what-is-type-floattype-in-golang
What is type FloatType in Golang?
Both the float32 and float64 data types represent numbers with decimal components.
🌐
Medium
waclawthedev.medium.com › inaccurate-float32-and-float64-how-to-avoid-the-trap-in-go-golang-6de59e66aed9
Inaccurate float32 and float64: how to avoid the trap in Go (golang) | by Wacław The Developer | Medium
December 14, 2021 - Inaccurate float32 and float64: how to avoid the trap in Go (golang) Hi everyone! Let’s talk about floats today. So, let’s take a look on that simple code: var n float64 = 0 for i := 0; i
🌐
gosamples
gosamples.dev › tutorials › the maximum and minimum value of the float types in go
📊 The maximum and minimum value of the float types in Go
April 14, 2022 - The maximum value of the float64 type in Go is 1.79769313486231570814527423731704356798070e+308 and you can get this value using the math.MaxFloat64 constant.
🌐
Google Groups
groups.google.com › g › golang-nuts › c › 3Io9xRmqAWM
go execution speed for float64 based calculations vs float32
I note that this issue has been dealt with in a previous post https://groups.google.com/forum/#!topic/golang-nuts/n12khle-mlY · The gist of which seems to suggest that 32-bit is faster than 64 · On Sunday, April 21, 2019 at 10:09:09 PM UTC-4, Robert Engels wrote: At least on intel, float64 should be faster than float32 since all math is done on the fpu in 64 bits, so it needs to be converted, but the memory bus also comes into play.
🌐
DigitalOcean
digitalocean.com › community › tutorials › understanding-data-types-in-go
Understanding Data Types in Go | DigitalOcean
May 1, 2019 - In the following example we will declare a variable called pi of type float64.
🌐
Go Packages
pkg.go.dev › math › big
big package - math/big - Go Packages
Float64 returns the float64 value nearest to x. If x is too small to be represented by a float64 (|x| < math.SmallestNonzeroFloat64), the result is (0, Below) or (-0, Above), respectively, depending on the sign of x.
🌐
ZetCode
zetcode.com › golang › builtins-float64-type
Understanding the float64 Type in Golang
May 8, 2025 - The float64 type represents 64-bit floating-point numbers in Go. It provides about 15 decimal digits of precision and is the default type for floating-point literals.
🌐
GoLinuxCloud
golinuxcloud.com › home › how to convert float64 to int golang? [solved]
How to convert float64 to int Golang? [SOLVED] | GoLinuxCloud
December 29, 2022 - The most convenient way to convert from a float64 to an int is directly cast a float to an int. The below example shows how we can cast a float to an int in Golang: