Search code examples
gofloating-accuracy

Implementation details of fmt.Println in golang


Consider this code

import (
  "fmt"
  "math/big"
)

func main() {
    var b1,b2,b3,bigSum big.Float

    b1.SetFloat64(25.3)
    b2.SetFloat64(76.2)
    b1.SetFloat64(53.1)

    bigSum.Add(&b1, &b2).Add(&b3, &bigSum)

    fmt.Println(bigSum)   // {53 0 0 1 false [9317046909104082944] 8}
    fmt.Println(&bigSum)  // 129.3
 }

I have 2 questions

  1. Why I have to pass bigSum as reference (by using &) to get the correct answer, otherwise we'll get back an object?

  2. How does Println work in Go? I mean how does it know which format it should apply for different types?


Solution

    1. Println determines whether the value implements the Stringer interface. If it does then it will call the String() to get formatted value. big.Float implements it for pointer receiver so you have to pass a reference. Otherwise Println will detect that it's a struct and print all of it's fields using reflection
    2. Go is open sourced. You can see for yourself https://golang.org/src/fmt/print.go?#L738 It uses type switches and reflection.