Convert floats to int64.
Following the example of bitcoind and the bitcoin wiki, provide a function to convert floats (which are returned by the json-rpc server) to int64 (which is the normal representation for most values involving bitcoins).
This commit is contained in:
parent
39cef5e76a
commit
86f848ddd4
3 changed files with 67 additions and 2 deletions
33
jsonapi.go
33
jsonapi.go
|
@ -742,3 +742,36 @@ func IsValidIdType(id interface{}) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSONToAmount Safely converts a floating point value to an int.
|
||||||
|
// Clearly not all floating point numbers can be converted to ints (there
|
||||||
|
// is no one-to-one mapping, but bitcoin's json api returns most numbers as
|
||||||
|
// floats which are not safe to use when handling money. Since bitcoins can
|
||||||
|
// only be divided in a limited way, this methods works for the amounts returned
|
||||||
|
// by the json api. It is not for general use.
|
||||||
|
// This follows the method described at:
|
||||||
|
// https://en.bitcoin.it/wiki/Proper_Money_Handling_%28JSON-RPC%29
|
||||||
|
func JSONToAmount(jsonAmount float64) (int64, error) {
|
||||||
|
var amount int64
|
||||||
|
var err error
|
||||||
|
if jsonAmount > 1.797693134862315708145274237317043567981e+300 {
|
||||||
|
err := fmt.Errorf("Error %d is too large to convert", jsonAmount)
|
||||||
|
return amount, err
|
||||||
|
}
|
||||||
|
if jsonAmount < -1.797693134862315708145274237317043567981e+300 {
|
||||||
|
err := fmt.Errorf("Error %d is too small to convert", jsonAmount)
|
||||||
|
return amount, err
|
||||||
|
}
|
||||||
|
tempVal := 1e8 * jsonAmount
|
||||||
|
// So we round properly. float won't == 0 and if it did, that
|
||||||
|
// would be converted fine anyway.
|
||||||
|
if tempVal < 0 {
|
||||||
|
tempVal = tempVal - 0.5
|
||||||
|
}
|
||||||
|
if tempVal > 0 {
|
||||||
|
tempVal = tempVal + 0.5
|
||||||
|
}
|
||||||
|
// Then just rely on the integer truncating
|
||||||
|
amount = int64(tempVal)
|
||||||
|
return amount, err
|
||||||
|
}
|
||||||
|
|
|
@ -256,7 +256,7 @@ var idtests = []struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestIsValidIdType tests that IsValidIdType allows (and disallows the correct
|
// TestIsValidIdType tests that IsValidIdType allows (and disallows the correct
|
||||||
// types.
|
// types).
|
||||||
func TestIsValidIdType(t *testing.T) {
|
func TestIsValidIdType(t *testing.T) {
|
||||||
for _, tt := range idtests {
|
for _, tt := range idtests {
|
||||||
res := btcjson.IsValidIdType(tt.testId[0])
|
res := btcjson.IsValidIdType(tt.testId[0])
|
||||||
|
@ -266,3 +266,34 @@ func TestIsValidIdType(t *testing.T) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var floattests = []struct {
|
||||||
|
in float64
|
||||||
|
out int64
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{1.0, 100000000, true},
|
||||||
|
{-1.0, -100000000, true},
|
||||||
|
{0.0, 0, true},
|
||||||
|
{0.00000001, 1, true},
|
||||||
|
{-0.00000001, -1, true},
|
||||||
|
{-1.0e307, 0, false},
|
||||||
|
{1.0e307, 0, false},
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestJSONtoAmount tests that JSONtoAmount returns the proper values.
|
||||||
|
func TestJSONtoAmount(t *testing.T) {
|
||||||
|
for _, tt := range floattests {
|
||||||
|
res, err := btcjson.JSONToAmount(tt.in)
|
||||||
|
if tt.pass {
|
||||||
|
if res != tt.out || err != nil {
|
||||||
|
t.Errorf("Should not fail: ", tt.in)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Should not pass: ", tt.in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
github.com/conformal/btcjson/jsonapi.go CreateMessage 100.00% (310/310)
|
github.com/conformal/btcjson/jsonapi.go CreateMessage 100.00% (310/310)
|
||||||
|
github.com/conformal/btcjson/jsonapi.go JSONToAmount 100.00% (15/15)
|
||||||
github.com/conformal/btcjson/jsonfxns.go jsonRpcSend 100.00% (7/7)
|
github.com/conformal/btcjson/jsonfxns.go jsonRpcSend 100.00% (7/7)
|
||||||
github.com/conformal/btcjson/jsonfxns.go MarshallAndSend 100.00% (7/7)
|
github.com/conformal/btcjson/jsonfxns.go MarshallAndSend 100.00% (7/7)
|
||||||
github.com/conformal/btcjson/jsonfxns.go GetRaw 100.00% (6/6)
|
github.com/conformal/btcjson/jsonfxns.go GetRaw 100.00% (6/6)
|
||||||
|
@ -7,5 +8,5 @@ github.com/conformal/btcjson/jsonapi.go jsonWithArgs 100.00% (5/5)
|
||||||
github.com/conformal/btcjson/jsonapi.go IsValidIdType 100.00% (3/3)
|
github.com/conformal/btcjson/jsonapi.go IsValidIdType 100.00% (3/3)
|
||||||
github.com/conformal/btcjson/jsonapi.go RpcCommand 66.67% (18/27)
|
github.com/conformal/btcjson/jsonapi.go RpcCommand 66.67% (18/27)
|
||||||
github.com/conformal/btcjson/jsonapi.go readResultCmd 40.00% (20/50)
|
github.com/conformal/btcjson/jsonapi.go readResultCmd 40.00% (20/50)
|
||||||
github.com/conformal/btcjson --------------- 90.60% (376/415)
|
github.com/conformal/btcjson --------------- 90.93% (391/430)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue