shopspring / decimal

Arbitrary-precision fixed-point decimal numbers in Go
Other
6.41k stars 623 forks source link

Why is my var printing 0? #350

Closed kharabela closed 9 months ago

kharabela commented 9 months ago

https://go.dev/play/p/FsJIRCO21KL

package main

import ( "fmt"

"github.com/shopspring/decimal"

)

func main() { var tot decimal.Decimal price, err := decimal.NewFromString("136.02") if err != nil { panic(err) }

quantity := decimal.NewFromInt(3)
tot.Add(quantity)
tot.Add(decimal.NewFromInt(5))
fee, _ := decimal.NewFromString(".035")
taxRate, _ := decimal.NewFromString(".08875")

subtotal := price.Mul(quantity)

preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1)))

total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1)))

fmt.Println("Subtotal:", subtotal)                      // Subtotal: 408.06
fmt.Println("Pre-tax:", preTax)                         // Pre-tax: 422.3421
fmt.Println("Taxes:", total.Sub(preTax))                // Taxes: 37.482861375
fmt.Println("Total:", total)                            // Total: 459.824961375
fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875

fmt.Println("Tot: ", tot)//prints 0

}

mwoss commented 9 months ago

Hi @kharabela. The decimal struct is immutable, thus every method call returns a new decimal. This was done to prevent common mistakes, see more in our FAQ.

In your case, you initialized the tot variable (zero-value of Decimal is 0), and after that called Add twice but, not used a return value anywhere. If you want to see proper result value you should

var tot decimal.Decimal

price, err := decimal.NewFromString("136.02")
if err != nil {
  panic(err)
}

quantity := decimal.NewFromInt(3)

result := tot.Add(quantity).Add(decimal.NewFromInt(5))
fmt.Println("Result: ", result )
}
kharabela commented 9 months ago

Thanks, how can I use in loop.I want to sum all values in loop.Please point me to an url if this is provided in document package main import ( "fmt" "github.com/shopspring/decimal" ) func main() { var result decimal.Decimal

for i := 1; i < 4; i++ {
    final := result.Add(decimal.NewFromInt(5))
    fmt.Println(final)
}

}

mwoss commented 9 months ago

if you want to sum a collection of decimals you can use Sum function or create result type and use it to sum all values in loop:

var result decimal.Decimal
for i := 1; i < 4; i++ {
    result = result.Add(decimal.NewFromInt(5))
}
fmt.Println(result)