1

Can someone tell the right way to calculate finance data in Go. I tryed to use big.Float but prob I miss something. The core goal is to calculate numbers with flaoting point and precision from 2 to 4 without any losses. 0.15 + 0.15 always should be 0.30. float try: https://play.golang.org/p/_3CXtRRNcA0 big.Float try: https://play.golang.org/p/zegE__Dit1O

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
gorush322
  • 19
  • 1
  • 2

2 Answers2

6

Floating-point is imprecise. Use integers (int64) scaled to cents or fractional cents.


For example, cents,

package main

import (
    "fmt"
)

func main() {
    cents := int64(0)
    for i := 0; i <= 2; i++ {
        cents += 15
        fmt.Println(cents)
    }
    fmt.Printf("$%d.%02d\n", cents/100, cents%100)
}

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

Output:

15
30
45
$0.45

For example, hundredths of a cent rounded,

package main

import "fmt"

func main() {
    c := int64(0) // hundredths of a cent
    for i := 0; i <= 2; i++ {
        c += 1550
        fmt.Println(c)
    }
    c += 50 // rounded
    fmt.Printf("$%d.%02d\n", c/10000, c%10000/100)
}

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

Output:

1550
3100
4650
$0.47
peterSO
  • 158,998
  • 31
  • 281
  • 276
  • 2
    `int64` cents is pretty good: it gets you to about $92 quadrillion. You might need mills (https://financial-dictionary.thefreedictionary.com/mill) for some financial software in which case you're down to just $9 quadrillion :-) – torek Sep 25 '19 at 03:34
  • @torke: Or if you're working with [US fueling stations](https://i.ebayimg.com/images/g/y6MAAOSw8cNUUpMn/s-l300.jpg). – Jonathan Hall Sep 25 '19 at 07:10
0

you can try https://github.com/shopspring/decimal if you really concern about precision,

try this code:

package main

import (
    "fmt"

    "github.com/shopspring/decimal"
)

func main() {

    z := decimal.NewFromFloat(0)

    b := decimal.NewFromFloat(0.15)

    z = z.Add(b)
    z = z.Add(b)
    z = z.Add(b)

    fmt.Println("z value:", z)

    testz := z.Cmp(decimal.NewFromFloat(0.45)) == 0

    fmt.Println("is z pass the test? ", testz)

}

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

Output:

z value: 0.45
is z pass the test?  true