You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
4.7 KiB

  1. package common
  2. import (
  3. "fmt"
  4. "math/big"
  5. "testing"
  6. "github.com/hermeznetwork/tracerr"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. )
  10. func TestConversionsFloat40(t *testing.T) {
  11. testVector := map[Float40]string{
  12. 6*0x800000000 + 123: "123000000",
  13. 2*0x800000000 + 4545: "454500",
  14. 30*0x800000000 + 10235: "10235000000000000000000000000000000",
  15. 0x000000000: "0",
  16. 0x800000000: "0",
  17. 0x0001: "1",
  18. 0x0401: "1025",
  19. 0x800000000 + 1: "10",
  20. 0xFFFFFFFFFF: "343597383670000000000000000000000000000000",
  21. }
  22. for test := range testVector {
  23. fix, err := test.BigInt()
  24. require.NoError(t, err)
  25. assert.Equal(t, fix.String(), testVector[test])
  26. bi, ok := new(big.Int).SetString(testVector[test], 10)
  27. require.True(t, ok)
  28. fl, err := NewFloat40(bi)
  29. assert.NoError(t, err)
  30. fx2, err := fl.BigInt()
  31. require.NoError(t, err)
  32. assert.Equal(t, fx2.String(), testVector[test])
  33. }
  34. }
  35. func TestExpectError(t *testing.T) {
  36. testVector := map[string]error{
  37. "9922334455000000000000000000000000000000": nil,
  38. "9922334455000000000000000000000000000001": ErrFloat40NotEnoughPrecission,
  39. "9922334454999999999999999999999999999999": ErrFloat40NotEnoughPrecission,
  40. "42949672950000000000000000000000000000000": nil,
  41. "99223344556573838487575": ErrFloat40NotEnoughPrecission,
  42. "992233445500000000000000000000000000000000": ErrFloat40E31,
  43. "343597383670000000000000000000000000000000": nil,
  44. "343597383680000000000000000000000000000000": ErrFloat40NotEnoughPrecission,
  45. "343597383690000000000000000000000000000000": ErrFloat40NotEnoughPrecission,
  46. "343597383700000000000000000000000000000000": ErrFloat40E31,
  47. }
  48. for test := range testVector {
  49. bi, ok := new(big.Int).SetString(test, 10)
  50. require.True(t, ok)
  51. _, err := NewFloat40(bi)
  52. assert.Equal(t, testVector[test], tracerr.Unwrap(err))
  53. }
  54. }
  55. func TestNewFloat40Floor(t *testing.T) {
  56. testVector := map[string][]string{
  57. // []int contains [Float40 value, Flot40 Floor value], when
  58. // Float40 value is expected to be 0, is because is expected to
  59. // be an error
  60. "9922334455000000000000000000000000000000": {
  61. "1040714485495", "1040714485495", "9922334455000000000000000000000000000000"},
  62. "9922334455000000000000000000000000000001": { // Floor [2] will be same as prev line
  63. "0", "1040714485495", "9922334455000000000000000000000000000000"},
  64. "9922334454999999999999999999999999999999": {
  65. "0", "1040714485494", "9922334454000000000000000000000000000000"},
  66. "42949672950000000000000000000000000000000": {
  67. "1069446856703", "1069446856703", "42949672950000000000000000000000000000000"},
  68. "99223344556573838487575": {
  69. "0", "456598933239", "99223344550000000000000"},
  70. "992233445500000000000000000000000000000000": {
  71. "0", "0", "0"}, // e>31, returns 0, err
  72. "343597383670000000000000000000000000000000": {
  73. "1099511627775", "1099511627775", "343597383670000000000000000000000000000000"},
  74. "343597383680000000000000000000000000000000": {
  75. "0", "0", "0"}, // e>31, returns 0, err
  76. "1157073197879933027": {
  77. "0", "286448638922", "1157073197800000000"},
  78. }
  79. for test := range testVector {
  80. bi, ok := new(big.Int).SetString(test, 10)
  81. require.True(t, ok)
  82. f40, err := NewFloat40(bi)
  83. if f40 == 0 {
  84. assert.Error(t, err)
  85. } else {
  86. assert.NoError(t, err)
  87. }
  88. assert.Equal(t, testVector[test][0], fmt.Sprint(uint64(f40)))
  89. f40, err = NewFloat40Floor(bi)
  90. if f40 == 0 {
  91. assert.Equal(t, ErrFloat40E31, tracerr.Unwrap(err))
  92. } else {
  93. assert.NoError(t, err)
  94. }
  95. assert.Equal(t, testVector[test][1], fmt.Sprint(uint64(f40)))
  96. bi2, err := f40.BigInt()
  97. require.NoError(t, err)
  98. assert.Equal(t, fmt.Sprint(testVector[test][2]), bi2.String())
  99. }
  100. }
  101. func BenchmarkFloat40(b *testing.B) {
  102. newBigInt := func(s string) *big.Int {
  103. bigInt, ok := new(big.Int).SetString(s, 10)
  104. if !ok {
  105. panic("Can not convert string to *big.Int")
  106. }
  107. return bigInt
  108. }
  109. type pair struct {
  110. Float40 Float40
  111. BigInt *big.Int
  112. }
  113. testVector := []pair{
  114. {6*0x800000000 + 123, newBigInt("123000000")},
  115. {2*0x800000000 + 4545, newBigInt("454500")},
  116. {30*0x800000000 + 10235, newBigInt("10235000000000000000000000000000000")},
  117. {0x000000000, newBigInt("0")},
  118. {0x800000000, newBigInt("0")},
  119. {0x0001, newBigInt("1")},
  120. {0x0401, newBigInt("1025")},
  121. {0x800000000 + 1, newBigInt("10")},
  122. {0xFFFFFFFFFF, newBigInt("343597383670000000000000000000000000000000")},
  123. }
  124. b.Run("NewFloat40()", func(b *testing.B) {
  125. for i := 0; i < b.N; i++ {
  126. _, _ = NewFloat40(testVector[i%len(testVector)].BigInt)
  127. }
  128. })
  129. b.Run("Float40.BigInt()", func(b *testing.B) {
  130. for i := 0; i < b.N; i++ {
  131. _, _ = testVector[i%len(testVector)].Float40.BigInt()
  132. }
  133. })
  134. }