使用mgo进行精确小数计算

huangapple go评论81阅读模式
英文:

Go precise decimals with mgo

问题

我正在编写一个应用程序,其中涉及到货币,并且需要非常精确的数字。我还使用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)
}

以上是您要运行的代码。

英文:

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(
  &quot;fmt&quot;
  &quot;math/big&quot;
  &quot;labix.org/v2/mgo&quot;
)

var mgoSession *mgo.Session

type Test struct{
  Budget big.Rat
}

func MongoLog(table string, pointer interface{}) {
  err := mgoSession.DB(&quot;db_log&quot;).C(table).Insert(pointer)
  if err != nil {
    panic(err)
  }
}

func main(){
  var err error
  mgoSession, err = mgo.Dial(&quot;localhost:27017&quot;)
  defer mgoSession.Close()
  if err != nil {
    panic(err)
  }

  cmp := big.NewRat(1, 100000)
  var test = Test{Budget : *big.NewRat(5, 10)}
  MongoLog(&quot;test&quot;, &amp;test)
  for i := 0; i &lt; 20; i++{
    fmt.Printf(&quot;Printf: %s\n&quot;, test.Budget.FloatString(10))
    fmt.Println(&quot;Println:&quot;, test.Budget, &quot;\n&quot;)
    test.Budget.Sub(&amp;test.Budget, cmp)
//    test.Budget = test.Budget - cpm
  }
  MongoLog(&quot;test&quot;, &amp;test)
}

答案1

得分: 3

big.Rat基本上是一对未导出的big.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应该可以满足大多数用例。

英文:

big.Rat is basically a pair of unexported <strike>int</strike> 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.

huangapple
  • 本文由 发表于 2014年1月12日 01:23:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/21065415.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定