diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index d452bc8a3..160e51db2 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -455,7 +455,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error { cache := newCachedDao(bc.dao.store) fee := bc.getSystemFeeAmount(block.PrevHash) for _, tx := range block.Transactions { - fee += uint32(bc.SystemFee(tx).Int64Value()) + fee += uint32(bc.SystemFee(tx).IntegralValue()) } if err := cache.StoreAsBlock(block, fee); err != nil { return err diff --git a/pkg/core/transaction/contract_test.go b/pkg/core/transaction/contract_test.go index fe3a7348e..dbdd21130 100644 --- a/pkg/core/transaction/contract_test.go +++ b/pkg/core/transaction/contract_test.go @@ -23,7 +23,8 @@ func TestEncodeDecodeContract(t *testing.T) { assert.Equal(t, "eec17cc828d6ede932b57e4eaf79c2591151096a7825435cd67f498f9fa98d88", input.PrevHash.StringLE()) assert.Equal(t, 0, int(input.PrevIndex)) - assert.Equal(t, int64(706), tx.Outputs[0].Amount.Int64Value()) + assert.Equal(t, int64(706), tx.Outputs[0].Amount.IntegralValue()) + assert.Equal(t, int32(0), tx.Outputs[0].Amount.FractionalValue()) assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Outputs[0].AssetID.StringLE()) assert.Equal(t, "a8666b4830229d6a1a9b80f6088059191c122d2b", tx.Outputs[0].ScriptHash.String()) assert.Equal(t, "bdf6cc3b9af12a7565bda80933a75ee8cef1bc771d0d58effc08e4c8b436da79", tx.Hash().StringLE()) diff --git a/pkg/util/fixed8.go b/pkg/util/fixed8.go index 6604f0f38..c511f76de 100644 --- a/pkg/util/fixed8.go +++ b/pkg/util/fixed8.go @@ -46,11 +46,18 @@ func (f Fixed8) FloatValue() float64 { return float64(f) / decimals } -// Int64Value returns the original value representing Fixed8 as int64. -func (f Fixed8) Int64Value() int64 { +// IntegralValue returns integer part of the original value representing +// Fixed8 as int64. +func (f Fixed8) IntegralValue() int64 { return int64(f) / decimals } +// FractionalValue returns decimal part of the original value. It has the same +// sign as f, so that f = f.IntegralValue() + f.FractionalValue(). +func (f Fixed8) FractionalValue() int32 { + return int32(int64(f) % decimals) +} + // Fixed8FromInt64 returns a new Fixed8 type multiplied by decimals. func Fixed8FromInt64(val int64) Fixed8 { return Fixed8(decimals * val) diff --git a/pkg/util/fixed8_test.go b/pkg/util/fixed8_test.go index 893cc86dc..5f01dee12 100644 --- a/pkg/util/fixed8_test.go +++ b/pkg/util/fixed8_test.go @@ -2,6 +2,7 @@ package util import ( "encoding/json" + "math" "strconv" "testing" @@ -16,7 +17,8 @@ func TestFixed8FromInt64(t *testing.T) { for _, val := range values { assert.Equal(t, Fixed8(val*decimals), Fixed8FromInt64(val)) - assert.Equal(t, val, Fixed8FromInt64(val).Int64Value()) + assert.Equal(t, val, Fixed8FromInt64(val).IntegralValue()) + assert.Equal(t, int32(0), Fixed8FromInt64(val).FractionalValue()) } } @@ -35,7 +37,8 @@ func TestFixed8Sub(t *testing.T) { b := Fixed8FromInt64(34) c := a.Sub(b) - assert.Equal(t, int64(8), c.Int64Value()) + assert.Equal(t, int64(8), c.IntegralValue()) + assert.Equal(t, int32(0), c.FractionalValue()) } func TestFixed8FromFloat(t *testing.T) { @@ -44,6 +47,10 @@ func TestFixed8FromFloat(t *testing.T) { for _, val := range inputs { assert.Equal(t, Fixed8(val*decimals), Fixed8FromFloat(val)) assert.Equal(t, val, Fixed8FromFloat(val).FloatValue()) + trunc := math.Trunc(val) + rem := (val - trunc) * decimals + assert.Equal(t, int64(trunc), Fixed8FromFloat(val).IntegralValue()) + assert.Equal(t, int32(math.Round(rem)), Fixed8FromFloat(val).FractionalValue()) } }