使用mgo实现精确小数位的Go编程技巧

3

我正在编写一个应用程序,在其中使用货币,并希望得到非常精确的数字。我还使用mgo在某些应用程序后存储结果。我想知道是否有一种方法可以在结构中使用math.Rat或godec,并将其存储为mgo中的数字?

这是我希望运行的代码:

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\n", test.Budget.FloatString(10))
    fmt.Println("Println:", test.Budget, "\n")
    test.Budget.Sub(&test.Budget, cmp)
//    test.Budget = test.Budget - cpm
  }
  MongoLog("test", &test)
}

你的代码为什么不能运行呢? - nemo
1
因为MongoDB不知道如何存储一个big.Rat。 - Gary
你可以只存储大数的“字符串”表示。 - fabrizioM
请查看以下网址:https://github.com/shopspring/decimal - Ezequiel Moreno
1个回答

3

big.Rat基本上是一对未公开的intbig.Int值,分别描述有理数的分子和分母。

您可以通过(*big.Rat).Denom(*big.Rat).Num轻松获取这两个数字。

然后将它们存储在您自己的结构中,具有导出(大写)字段:

type CurrencyValue struct {
    Denom int64
    Num   int64
}

使用mgo进行存储,并通过big.NewRat在应用程序中将其转换回* big.Rat

编辑:

评论中的Nick Craig-Wood正确指出,实际上big.Rat由2个big.Int值组成,而不是我写的int值(易于忽略大写i)。很难在BSON中表示一个big.Int,但是int64应该涵盖大多数用例。


4
big.Rat是一对具有无限精度的big.Int,因此可能无法适应CurrencyValue结构中的int。我不同意@Rick-777的观点——big.Rat具有无限精度而不是32位。 - Nick Craig-Wood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接