package common import ( "fmt" "math/big" "testing" "github.com/hermeznetwork/tracerr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestConversionsFloat40(t *testing.T) { testVector := map[Float40]string{ 6*0x800000000 + 123: "123000000", 2*0x800000000 + 4545: "454500", 30*0x800000000 + 10235: "10235000000000000000000000000000000", 0x000000000: "0", 0x800000000: "0", 0x0001: "1", 0x0401: "1025", 0x800000000 + 1: "10", 0xFFFFFFFFFF: "343597383670000000000000000000000000000000", } for test := range testVector { fix, err := test.BigInt() require.NoError(t, err) assert.Equal(t, fix.String(), testVector[test]) bi, ok := new(big.Int).SetString(testVector[test], 10) require.True(t, ok) fl, err := NewFloat40(bi) assert.NoError(t, err) fx2, err := fl.BigInt() require.NoError(t, err) assert.Equal(t, fx2.String(), testVector[test]) } } func TestExpectError(t *testing.T) { testVector := map[string]error{ "9922334455000000000000000000000000000000": nil, "9922334455000000000000000000000000000001": ErrFloat40NotEnoughPrecission, "9922334454999999999999999999999999999999": ErrFloat40NotEnoughPrecission, "42949672950000000000000000000000000000000": nil, "99223344556573838487575": ErrFloat40NotEnoughPrecission, "992233445500000000000000000000000000000000": ErrFloat40E31, "343597383670000000000000000000000000000000": nil, "343597383680000000000000000000000000000000": ErrFloat40NotEnoughPrecission, "343597383690000000000000000000000000000000": ErrFloat40NotEnoughPrecission, "343597383700000000000000000000000000000000": ErrFloat40E31, } for test := range testVector { bi, ok := new(big.Int).SetString(test, 10) require.True(t, ok) _, err := NewFloat40(bi) assert.Equal(t, testVector[test], tracerr.Unwrap(err)) } } func TestNewFloat40Floor(t *testing.T) { 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", "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) require.True(t, ok) f40, err := NewFloat40(bi) if f40 == 0 { assert.Error(t, err) } else { assert.NoError(t, err) } assert.Equal(t, testVector[test][0], fmt.Sprint(uint64(f40))) f40, err = NewFloat40Floor(bi) if f40 == 0 { assert.Equal(t, ErrFloat40E31, tracerr.Unwrap(err)) } else { assert.NoError(t, err) } 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()) } } func BenchmarkFloat40(b *testing.B) { newBigInt := func(s string) *big.Int { bigInt, ok := new(big.Int).SetString(s, 10) if !ok { panic("Can not convert string to *big.Int") } return bigInt } type pair struct { Float40 Float40 BigInt *big.Int } testVector := []pair{ {6*0x800000000 + 123, newBigInt("123000000")}, {2*0x800000000 + 4545, newBigInt("454500")}, {30*0x800000000 + 10235, newBigInt("10235000000000000000000000000000000")}, {0x000000000, newBigInt("0")}, {0x800000000, newBigInt("0")}, {0x0001, newBigInt("1")}, {0x0401, newBigInt("1025")}, {0x800000000 + 1, newBigInt("10")}, {0xFFFFFFFFFF, newBigInt("343597383670000000000000000000000000000000")}, } b.Run("NewFloat40()", func(b *testing.B) { for i := 0; i < b.N; i++ { _, _ = NewFloat40(testVector[i%len(testVector)].BigInt) } }) b.Run("Float40.BigInt()", func(b *testing.B) { for i := 0; i < b.N; i++ { _, _ = testVector[i%len(testVector)].Float40.BigInt() } }) }