To expand on Diego's answer, you have the line

var ratex float64 = 1 + interest

before interest is defined, so it is 0 and ratex becomes 1. Then you have the line

var logi float64 = math.Log(ratex)

and since ratex is 1, and the log of 1 is 0, logi becomes 0. You then define the period by dividing by logi, which is 0, so you will get +inf.

What you should do is assign the value to ratex after you have gotten the input for what the interest is.

Answer from Derek on Stack Overflow
🌐
Google Groups
groups.google.com › g › golang-nuts › c › BVyo-QQO8xg
Assigning +Inf to a float32 ..
Couldn't find a way to do this - not even in the math package .. (I see that +Inf is in the math package but it is not exported) ie lines 8-10 in math/bits.go ... In https://golang.org/ref/spec#Numeric_types it states "float32 the set of all IEEE-754 32-bit floating-point numbers"
🌐
Educative
educative.io › answers › what-is-type-float32-in-golang
What is type float32 in Golang?
The following code shows what happens if you try to store something larger than the stipulated range of values in a float32 variable: ... As we can see from the outputs of the code above, when we stored the max magnitude of a negative number of -3.4E+38 in num and printed it, the value came out to be as what was stored. However, when we multiplied it by 10, the value was pushed out of the allowed range, which resulted in the stored value being interpreted as negative infinity -Inf when printed again.
🌐
Go Packages
pkg.go.dev › math
math - Go Packages - Golang
Nextafter32 returns the next representable float32 value after x towards y. ... Pow returns x**y, the base-x exponential of y. ... Pow(x, ±0) = 1 for any x Pow(1, y) = 1 for any y Pow(x, 1) = x for any x Pow(NaN, y) = NaN Pow(x, NaN) = NaN Pow(±0, y) = ±Inf for y an odd integer < 0 Pow(±0, -Inf) = +Inf Pow(±0, +Inf) = +0 Pow(±0, y) = +Inf for finite y < 0 and not an odd integer Pow(±0, y) = ±0 for y an odd integer > 0 Pow(±0, y) = +0 for finite y > 0 and not an odd integer Pow(-1, ±Inf) = 1 Pow(x, +Inf) = +Inf for |x| > 1 Pow(x, -Inf) = +0 for |x| > 1 Pow(x, +Inf) = +0 for |x| < 1 Pow(x, -Inf) = +Inf for |x| < 1 Pow(+Inf, y) = +Inf for y > 0 Pow(+Inf, y) = +0 for y < 0 Pow(-Inf, y) = Pow(-0, -y) Pow(x, y) = NaN for finite x < 0 and finite non-integer y
🌐
Go Packages
pkg.go.dev › gonum.org › v1 › gonum › internal › math32
math32 package - gonum.org/v1/gonum/internal/math32 - Go Packages
... Abs returns the absolute value of x. ... Copysign returns a value with the magnitude of x and the sign of y. ... Hypot returns Sqrt(p*p + q*q), taking care to avoid unnecessary overflow and underflow. ... Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
🌐
ZetCode
zetcode.com › golang › builtins-float32-type
Understanding the float32 Type in Golang
May 8, 2025 - package main import ( "fmt" "math" ) const epsilon = 1e-6 // Small threshold for comparison func main() { a := float32(0.1) b := float32(0.2) c := float32(0.3) // Problematic direct comparison fmt.Println("a + b == c?", a+b == c) // Better approach using epsilon sum := a + b diff := float32(math.Abs(float64(sum - c))) fmt.Println("Approximately equal?", diff < epsilon) // Special values nan := float32(math.NaN()) inf := float32(math.Inf(1)) fmt.Println("Is NaN?", math.IsNaN(float64(nan))) fmt.Println("Is Inf?", math.IsInf(float64(inf), 1)) }
🌐
Educative
educative.io › answers › what-is-the-inf-function-in-golang
What is the Inf function in golang?
The Go programming language uses the Inf function to generate an infinite value · To use this function, you must import the math package in your file and access the Inf function within it using the . notation (math.Inf).
🌐
GeeksforGeeks
geeksforgeeks.org › math-inf-function-in-golang-with-examples
math.Inf() Function in Golang With Examples - GeeksforGeeks
April 28, 2025 - So, you need to add a math package in your program with the help of the import keyword to access the Inf() function. Syntax: ... // Golang program to illustrate the // math.Inf() Function package main import ( "fmt" "math" ) // Main function ...
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

Find elsewhere
🌐
Go
go.dev › src › math › big › float.go
- The Go Programming Language
839 func (x *Float) Float32() (float32, Accuracy) { 840 if debugFloat { 841 x.validate() 842 } 843 844 switch x.form { 845 case finite: 846 // 0 < |x| < +Inf 847 848 const ( 849 fbits = 32 // float size 850 mbits = 23 // mantissa size (excluding implicit msb) 851 ebits = fbits - mbits - 1 // 8 exponent size 852 bias = 1<<(ebits-1) - 1 // 127 exponent bias 853 dmin = 1 - bias - mbits // -149 smallest unbiased exponent (denormal) 854 emin = 1 - bias // -126 smallest unbiased exponent (normal) 855 emax = bias // 127 largest unbiased exponent (normal) 856 ) 857 858 // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float32 mantissa.
🌐
Go Packages
pkg.go.dev › math › big
big package - math/big - Go Packages
Float32 returns the nearest float32 value for x and a bool indicating whether f represents x exactly. If the magnitude of x is too large to be represented by a float32, f is an infinity and exact is false.
🌐
IncludeHelp
includehelp.com › golang › math-inf-function-with-examples.aspx
Golang math.Inf() Function with Examples
September 1, 2021 - // Golang program to demonstrate the // example of math.Inf() Function package main import ( "fmt" "math" ) func main() { var x int var InfX float64 x = 0 InfX = math.Inf(x) fmt.Println("Inf(", x, ") = ", InfX) x = 1 InfX = math.Inf(x) fmt.Println("Inf(", x, ") = ", InfX) x = -1 InfX = math.Inf(x) fmt.Println("Inf(", x, ") = ", InfX) }
🌐
Go Packages
pkg.go.dev › git.maze.io › go › math32
math32 package - git.maze.io/go/math32 - Go Packages
Very large values overflow to -1 or +Inf. ... Float32bits returns the IEEE 754 binary representation of f.
🌐
Go Packages
pkg.go.dev › gopkg.in › inf.v0
inf package - gopkg.in/inf.v0 - Go Packages
NaN and Inf values, and distinguishing between positive and negative zero · conversions to and from float32/64 types · Features considered for possible addition: formatting options · Exp method · combined operations such as AddRound/MulAdd etc · exchanging data in decimal32/64/128 formats ·
Top answer
1 of 2
1

Custom handling of values can be done through custom types that implement the Marshaler interface. Your Something type, though, is malformed. It's defined as type Something interface{}, whereas that really ought the be a type Something struct:

type Something struct {
    Id      string    `firestore:"id"`
    NumberA JSONFloat `firestore:"numberA"`
    NumberB JSONFloat `firestore:"numberB"`
    NumberC JSONFloat `firestore:"numberC"`
}

type JSONFloat float64

func (j JSONFloat) MarshalJSON() ([]byte, error) {
    v := float64(j)
    if math.IsInf(j, 0) {
        // handle infinity, assign desired value to v
        // or say +/- indicates infinity
        s := "+"
        if math.IsInf(v, -1) {
            s = "-"
        }
        return []byte(s), nil
    }
    return json.Marshal(v) // marshal result as standard float64
}

func (j *JSONFloat) UnsmarshalJSON(v []byte) error {
    if s := string(v); s == "+" || s == "-" {
        // if +/- indiciates infinity
        if s == "+" {
            *j = JSONFloat(math.Inf(1))
            return nil
        }
        *j = JSONFloat(math.Inf(-1))
        return nil
    }
    // just a regular float value
    var fv float64
    if err := json.Unmarshal(v, &fv); err != nil {\
        return err
    }
    *j = JSONFloat(fv)
    return nil
}

That should do it

2 of 2
0

I created xhhuango/json to support NaN, +Inf, and -Inf.

type T struct {
    N  float64
    IP float64
    IN float64
}

func TestMarshalNaNAndInf(t *testing.T) {
    s := T{
        N:  math.NaN(),
        IP: math.Inf(1),
        IN: math.Inf(-1),
    }
    got, err := Marshal(s)
    if err != nil {
        t.Errorf("Marshal() error: %v", err)
    }
    want := `{"N":NaN,"IP":+Inf,"IN":-Inf}`
    if string(got) != want {
        t.Errorf("Marshal() = %s, want %s", got, want)
    }
}

func TestUnmarshalNaNAndInf(t *testing.T) {
    data := []byte(`{"N":NaN,"IP":+Inf,"IN":-Inf}`)
    var s T
    err := Unmarshal(data, &s)
    if err != nil {
        t.Fatalf("Unmarshal: %v", err)
    }
    if !math.IsNaN(s.N) || !math.IsInf(s.IP, 1) || !math.IsInf(s.IN, -1)     {
        t.Fatalf("after Unmarshal, s.N=%f, s.IP=%f, s.IN=%f, want NaN, +Inf, -Inf", s.N, s.IP, s.IN)
    }
}
🌐
Medium
medium.com › pragmatic-programmers › testing-floating-point-numbers-in-go-9872fe6de17f
Testing Floating Point Numbers in Go | by Ricardo Gerardi | The Pragmatic Programmers | Medium
December 21, 2021 - Ricardo Gerardi, author of Powerful Command-Line Applications in Go, gives us a helper function to calculate the relative difference between input numbers to help with testing floating-point numbers in Go (Golang).
🌐
GitHub
github.com › golang › go › issues › 59627
encoding/json: please document that float +inf/-inf/nan will cause json.Marshal return error · Issue #59627 · golang/go
April 14, 2023 - Document that float +inf/-inf/nan will cause json.Marshal return error or Not throwing serialization errors on basic numeric data types with valid state. What did you see instead? No document of this kind of thing and return json: unsupported value: NaN · Should golang standard library document possible/common error type of a package or a function like windows api document(https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilew) or linux man (https://linux.die.net/man/3/mmap)?
Author   bronze1man
🌐
GitHub
github.com › golang › go › issues › 19405
spec: Float to int conversions underspecified · Issue #19405 · golang/go
March 5, 2017 - package main import ( "fmt" "math" ) func main() { f := float32(math.MaxInt32 - 64) i := int32(f) fmt.Printf("%.10v, %v %#x\n", f, i, i) f = float32(math.MaxInt32 - 63) i = int32(f) fmt.Printf("%.10v, %v %#x\n", f, i, i) }
Author   cznic
🌐
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