diff --git a/common/float40.go b/common/float40.go index 432824a..92744b6 100644 --- a/common/float40.go +++ b/common/float40.go @@ -81,9 +81,9 @@ func (f40 Float40) BigInt() (*big.Int, error) { return r, nil } -// newFloat40ME takes a *big.Int integer and returns the m (mantissa) & e -// (exponent) from the Float40 representation -func newFloat40ME(f *big.Int) (*big.Int, *big.Int) { +// NewFloat40 encodes a *big.Int integer as a Float40, returning error in case +// of loss during the encoding. +func NewFloat40(f *big.Int) (Float40, error) { m := f e := big.NewInt(0) zero := big.NewInt(0) @@ -92,13 +92,6 @@ func newFloat40ME(f *big.Int) (*big.Int, *big.Int) { m = new(big.Int).Div(m, ten) e = new(big.Int).Add(e, big.NewInt(1)) } - return m, e -} - -// NewFloat40 encodes a *big.Int integer as a Float40, returning error in case -// of loss during the encoding. -func NewFloat40(f *big.Int) (Float40, error) { - m, e := newFloat40ME(f) if e.Int64() > 31 { return 0, tracerr.Wrap(ErrFloat40E31) } @@ -116,7 +109,14 @@ func NewFloat40(f *big.Int) (Float40, error) { // hermez-node, it's a helper for external usage to generate valid Float40 // values. func NewFloat40Floor(f *big.Int) (Float40, error) { - m, e := newFloat40ME(f) + m := f + e := big.NewInt(0) + // zero := big.NewInt(0) + ten := big.NewInt(10) + for m.Cmp(thres) >= 0 { + m = new(big.Int).Div(m, ten) + e = new(big.Int).Add(e, big.NewInt(1)) + } if e.Int64() > 31 { return 0, tracerr.Wrap(ErrFloat40E31) } diff --git a/common/float40_test.go b/common/float40_test.go index 0089332..9378d6a 100644 --- a/common/float40_test.go +++ b/common/float40_test.go @@ -1,6 +1,7 @@ package common import ( + "fmt" "math/big" "testing" @@ -61,20 +62,28 @@ func TestExpectError(t *testing.T) { } func TestNewFloat40Floor(t *testing.T) { - testVector := map[string][]uint64{ + testVector := map[string][]string{ // []int contains [Float40 value, Flot40 Floor value], when // Float40 value is expected to be 0, is because is expected to // be an error - "9922334455000000000000000000000000000000": {1040714485495, 1040714485495}, - "9922334455000000000000000000000000000001": {0, 6846188881046405121}, - "9922334454999999999999999999999999999999": {0, 6846188881046405119}, - "42949672950000000000000000000000000000000": {1069446856703, 1069446856703}, - "99223344556573838487575": {0, 16754928163869896727}, - "992233445500000000000000000000000000000000": {0, 0}, - "343597383670000000000000000000000000000000": {1099511627775, 1099511627775}, - "343597383680000000000000000000000000000000": {0, 1099511627776}, - "343597383690000000000000000000000000000000": {0, 1099511627777}, - "343597383700000000000000000000000000000000": {0, 0}, + "9922334455000000000000000000000000000000": { + "1040714485495", "1040714485495", "9922334455000000000000000000000000000000"}, + "9922334455000000000000000000000000000001": { // Floor [2] will be same as prev line + "0", "1040714485495", "9922334455000000000000000000000000000000"}, + "9922334454999999999999999999999999999999": { + "0", "1040714485494", "9922334454000000000000000000000000000000"}, + "42949672950000000000000000000000000000000": { + "1069446856703", "1069446856703", "42949672950000000000000000000000000000000"}, + "99223344556573838487575": { + "0", "456598933239", "99223344550000000000000"}, + "992233445500000000000000000000000000000000": { + "0", "0", "0"}, // e>31, returns 0, err + "343597383670000000000000000000000000000000": { + "1099511627775", "1099511627775", "343597383670000000000000000000000000000000"}, + "343597383680000000000000000000000000000000": { + "0", "0", "0"}, // e>31, returns 0, err + "1157073197879933027": { + "0", "286448638922", "1157073197800000000"}, } for test := range testVector { bi, ok := new(big.Int).SetString(test, 10) @@ -85,7 +94,7 @@ func TestNewFloat40Floor(t *testing.T) { } else { assert.NoError(t, err) } - assert.Equal(t, testVector[test][0], uint64(f40)) + assert.Equal(t, testVector[test][0], fmt.Sprint(uint64(f40))) f40, err = NewFloat40Floor(bi) if f40 == 0 { @@ -93,7 +102,11 @@ func TestNewFloat40Floor(t *testing.T) { } else { assert.NoError(t, err) } - assert.Equal(t, testVector[test][1], uint64(f40)) + assert.Equal(t, testVector[test][1], fmt.Sprint(uint64(f40))) + + bi2, err := f40.BigInt() + require.NoError(t, err) + assert.Equal(t, fmt.Sprint(testVector[test][2]), bi2.String()) } }