I am writing an application where I use money and want very accurate numbers. I am also using mgo to store the results after some application. I was wondering if there was a way for me to use math.Rat
or godec in a struct and have it store as a number in mgo?
This is the kind of code i was hoping to run:
package main
import(
"fmt"
"math/big"
"labix.org/v2/mgo"
)
var mgoSession *mgo.Session
type Test struct{
Budget big.Rat
}
func MongoLog(table string, pointer interface{}) {
err := mgoSession.DB("db_log").C(table).Insert(pointer)
if err != nil {
panic(err)
}
}
func main(){
var err error
mgoSession, err = mgo.Dial("localhost:27017")
defer mgoSession.Close()
if err != nil {
panic(err)
}
cmp := big.NewRat(1, 100000)
var test = Test{Budget : *big.NewRat(5, 10)}
MongoLog("test", &test)
for i := 0; i < 20; i++{
fmt.Printf("Printf: %s
", test.Budget.FloatString(10))
fmt.Println("Println:", test.Budget, "
")
test.Budget.Sub(&test.Budget, cmp)
// test.Budget = test.Budget - cpm
}
MongoLog("test", &test)
}
big.Rat
is basically a pair of unexported int
big.Int
values describing the numerator and denominator of a rational number, respectively.
You can easily get both numbers through (*big.Rat).Denom
and (*big.Rat).Num
.
Then store them in a structure of your own, with exported (upper case) fields:
type CurrencyValue struct {
Denom int64
Num int64
}
Store this with mgo
and convert it back to a *big.Rat
in your application through big.NewRat
Edit:
Nick Craig-Wood in the comments correctly noted that big.Rat
actually consists of 2 big.Int
values, not int
values as I had written (easy to miss the upper case i). It's hard to represent a big.Int
in BSON but, int64
should cover most use-cases.