code.vegaprotocol.io/vega@v0.79.0/libs/num/int_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package num_test
    17  
    18  import (
    19  	"math/rand"
    20  	"testing"
    21  
    22  	"code.vegaprotocol.io/vega/libs/num"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  func TestInt256Constructors(t *testing.T) {
    28  	// Positive number
    29  	var value1 int64 = 42
    30  	n := num.NewInt(value1)
    31  	assert.Equal(t, uint64(value1), n.U.Uint64())
    32  	assert.Equal(t, true, n.IsPositive())
    33  	assert.Equal(t, false, n.IsNegative())
    34  	assert.Equal(t, false, n.IsZero())
    35  
    36  	// Negative number
    37  	var value2 int64 = -42
    38  	n = num.NewInt(value2)
    39  	assert.Equal(t, uint64(-value2), n.U.Uint64())
    40  	assert.Equal(t, false, n.IsPositive())
    41  	assert.Equal(t, true, n.IsNegative())
    42  	assert.Equal(t, false, n.IsZero())
    43  
    44  	// Zero
    45  	var value3 int64
    46  	n = num.NewInt(value3)
    47  	assert.Equal(t, uint64(value3), n.U.Uint64())
    48  	assert.Equal(t, false, n.IsPositive())
    49  	assert.Equal(t, false, n.IsNegative())
    50  	assert.Equal(t, true, n.IsZero())
    51  }
    52  
    53  func TestIntFromUint(t *testing.T) {
    54  	n := num.NewUint(100)
    55  
    56  	// Test making a positive value
    57  	i := num.IntFromUint(n, true)
    58  	assert.Equal(t, uint64(100), i.U.Uint64())
    59  	assert.Equal(t, true, i.IsPositive())
    60  	assert.Equal(t, false, i.IsNegative())
    61  	assert.Equal(t, false, i.IsZero())
    62  
    63  	// Test making a negative value
    64  	i = num.IntFromUint(n, false)
    65  	assert.Equal(t, uint64(100), i.U.Uint64())
    66  	assert.Equal(t, false, i.IsPositive())
    67  	assert.Equal(t, true, i.IsNegative())
    68  	assert.Equal(t, false, i.IsZero())
    69  }
    70  
    71  func TestFlipSign(t *testing.T) {
    72  	n := num.NewInt(100)
    73  	assert.Equal(t, uint64(100), n.U.Uint64())
    74  	assert.Equal(t, true, n.IsPositive())
    75  	assert.Equal(t, false, n.IsNegative())
    76  	assert.Equal(t, false, n.IsZero())
    77  
    78  	n.FlipSign()
    79  	assert.Equal(t, uint64(100), n.U.Uint64())
    80  	assert.Equal(t, false, n.IsPositive())
    81  	assert.Equal(t, true, n.IsNegative())
    82  	assert.Equal(t, false, n.IsZero())
    83  }
    84  
    85  func TestClone(t *testing.T) {
    86  	n := num.NewInt(100)
    87  	n2 := n.Clone()
    88  
    89  	n2.FlipSign()
    90  	assert.Equal(t, true, n.IsPositive())
    91  	assert.Equal(t, true, n2.IsNegative())
    92  
    93  	n.AddSum(num.NewInt(50))
    94  	assert.Equal(t, uint64(150), n.U.Uint64())
    95  	assert.Equal(t, uint64(100), n2.U.Uint64())
    96  }
    97  
    98  func TestGT(t *testing.T) {
    99  	mid := num.NewInt(0)
   100  	low := num.NewInt(-10)
   101  	high := num.NewInt(10)
   102  
   103  	assert.Equal(t, true, mid.GT(low))
   104  	assert.Equal(t, false, mid.GT(high))
   105  	assert.Equal(t, false, low.GT(mid))
   106  	assert.Equal(t, false, low.GT(high))
   107  	assert.Equal(t, true, high.GT(mid))
   108  	assert.Equal(t, true, high.GT(low))
   109  
   110  	assert.Equal(t, false, mid.GT(mid))
   111  	assert.Equal(t, false, low.GT(low))
   112  	assert.Equal(t, false, high.GT(high))
   113  }
   114  
   115  func TestLT(t *testing.T) {
   116  	mid := num.NewInt(0)
   117  	low := num.NewInt(-10)
   118  	high := num.NewInt(10)
   119  
   120  	assert.Equal(t, false, mid.LT(low))
   121  	assert.Equal(t, true, mid.LT(high))
   122  	assert.Equal(t, true, low.LT(mid))
   123  	assert.Equal(t, true, low.LT(high))
   124  	assert.Equal(t, false, high.LT(mid))
   125  	assert.Equal(t, false, high.LT(low))
   126  
   127  	assert.Equal(t, false, mid.LT(mid))
   128  	assert.Equal(t, false, low.LT(low))
   129  	assert.Equal(t, false, high.LT(high))
   130  }
   131  
   132  func TestString(t *testing.T) {
   133  	mid := num.NewInt(0)
   134  	low := num.NewInt(-10)
   135  	high := num.NewInt(10)
   136  
   137  	assert.Equal(t, "0", mid.String())
   138  	assert.Equal(t, "-10", low.String())
   139  	assert.Equal(t, "10", high.String())
   140  }
   141  
   142  func TestAdd(t *testing.T) {
   143  	// Add positive to zero
   144  	i := num.NewInt(0)
   145  	i.Add(num.NewInt(10))
   146  	assert.Equal(t, "10", i.String())
   147  
   148  	// Add negative to zero
   149  	i = num.NewInt(0)
   150  	i.Add(num.NewInt(-10))
   151  	assert.Equal(t, "-10", i.String())
   152  
   153  	// Add zero to negative
   154  	i = num.NewInt(0)
   155  	i.Add(num.NewInt(0))
   156  	assert.Equal(t, "0", i.String())
   157  
   158  	// Add zero to positive
   159  	i = num.NewInt(10)
   160  	i.Add(num.NewInt(0))
   161  	assert.Equal(t, "10", i.String())
   162  
   163  	// Add zero to zero
   164  	i = num.NewInt(0)
   165  	i.Add(num.NewInt(0))
   166  	assert.Equal(t, "0", i.String())
   167  
   168  	// Add positive to positive
   169  	i = num.NewInt(10)
   170  	i.Add(num.NewInt(15))
   171  	assert.Equal(t, "25", i.String())
   172  
   173  	// Add negative to negative
   174  	i = num.NewInt(-10)
   175  	i.Add(num.NewInt(-15))
   176  	assert.Equal(t, "-25", i.String())
   177  
   178  	// Add positive to negative (no sign flip)
   179  	i = num.NewInt(-15)
   180  	i.Add(num.NewInt(10))
   181  	assert.Equal(t, "-5", i.String())
   182  
   183  	// Add positive to negative (sign flip)
   184  	i = num.NewInt(-10)
   185  	i.Add(num.NewInt(15))
   186  	assert.Equal(t, "5", i.String())
   187  
   188  	// Add negative to positive (no sign flip)
   189  	i = num.NewInt(10)
   190  	i.Add(num.NewInt(-5))
   191  	assert.Equal(t, "5", i.String())
   192  
   193  	// Add negative to positive (sign flip)
   194  	i = num.NewInt(10)
   195  	i.Add(num.NewInt(-15))
   196  	assert.Equal(t, "-5", i.String())
   197  }
   198  
   199  func TestMul(t *testing.T) {
   200  	// Mul positive-positive
   201  	i := num.NewInt(100)
   202  	i.Mul(num.NewInt(100))
   203  	assert.Equal(t, "10000", i.String())
   204  
   205  	// Mul negative-negative
   206  	i = num.NewInt(-100)
   207  	i.Mul(num.NewInt(-100))
   208  	assert.Equal(t, "10000", i.String())
   209  
   210  	// Mul positive-negative
   211  	i = num.NewInt(100)
   212  	i.Mul(num.NewInt(-100))
   213  	assert.Equal(t, "-10000", i.String())
   214  
   215  	// Mul negative-positive
   216  	i = num.NewInt(-100)
   217  	i.Mul(num.NewInt(100))
   218  	assert.Equal(t, "-10000", i.String())
   219  
   220  	// Mul zero-positive
   221  	i = num.NewInt(0)
   222  	i.Mul(num.NewInt(100))
   223  	assert.Equal(t, "0", i.String())
   224  
   225  	// Mul zero-negative
   226  	i = num.NewInt(0)
   227  	i.Mul(num.NewInt(-100))
   228  	assert.Equal(t, "0", i.String())
   229  }
   230  
   231  func TestDiv(t *testing.T) {
   232  	// Div positive-positive
   233  	i := num.NewInt(1000)
   234  	i.Div(num.NewInt(100))
   235  	assert.Equal(t, "10", i.String())
   236  
   237  	// Div negative-negative
   238  	i = num.NewInt(-1000)
   239  	i.Div(num.NewInt(-100))
   240  	assert.Equal(t, "10", i.String())
   241  
   242  	// Div positive-negative
   243  	i = num.NewInt(1000)
   244  	i.Div(num.NewInt(-100))
   245  	assert.Equal(t, "-10", i.String())
   246  
   247  	// Div negative-positive
   248  	i = num.NewInt(-1000)
   249  	i.Div(num.NewInt(100))
   250  	assert.Equal(t, "-10", i.String())
   251  
   252  	// Div zero-positive
   253  	i = num.NewInt(0)
   254  	i.Div(num.NewInt(100))
   255  	assert.Equal(t, "0", i.String())
   256  
   257  	// Div zero-negative
   258  	i = num.NewInt(0)
   259  	i.Div(num.NewInt(-100))
   260  	assert.Equal(t, "0", i.String())
   261  }
   262  
   263  func TestAddSum(t *testing.T) {
   264  	num1 := num.NewInt(10)
   265  	num2 := num.NewInt(20)
   266  	num3 := num.NewInt(-15)
   267  	num4 := num.NewInt(-30)
   268  	num5 := num.NewInt(10)
   269  
   270  	result := num1.AddSum(num2, num3, num4, num5)
   271  	assert.Equal(t, "-5", result.String())
   272  }
   273  
   274  func TestSubSum(t *testing.T) {
   275  	num1 := num.NewInt(10)
   276  	num2 := num.NewInt(20)
   277  	num3 := num.NewInt(-15)
   278  	num4 := num.NewInt(-30)
   279  	num5 := num.NewInt(10)
   280  
   281  	result := num1.SubSum(num2, num3, num4, num5)
   282  	assert.Equal(t, "25", result.String())
   283  }
   284  
   285  func TestBruteForce(t *testing.T) {
   286  	t.Run("brute force adds", testAddLoop)
   287  	t.Run("brute force subs", testSubLoop)
   288  }
   289  
   290  func testAddLoop(t *testing.T) {
   291  	for c := 0; c < 10000; c++ {
   292  		num1 := rand.Int63n(100) - 50
   293  		num2 := rand.Int63n(100) - 50
   294  
   295  		bigNum1 := num.NewInt(num1)
   296  		bigNum2 := num.NewInt(num2)
   297  
   298  		bigNum1.Add(bigNum2)
   299  
   300  		assert.Equal(t, num1+num2, bigNum1.Int64())
   301  	}
   302  }
   303  
   304  func testSubLoop(t *testing.T) {
   305  	for c := 0; c < 10000; c++ {
   306  		num1 := rand.Int63n(100) - 50
   307  		num2 := rand.Int63n(100) - 50
   308  
   309  		bigNum1 := num.NewInt(num1)
   310  		bigNum2 := num.NewInt(num2)
   311  
   312  		bigNum1.Sub(bigNum2)
   313  
   314  		assert.Equal(t, num1-num2, bigNum1.Int64())
   315  	}
   316  }
   317  
   318  func TestIntFromString(t *testing.T) {
   319  	n, hasError := num.IntFromString("100", 10)
   320  	assert.False(t, hasError)
   321  	assert.Equal(t, "100", n.String())
   322  
   323  	n, hasError = num.IntFromString("+100", 10)
   324  	assert.False(t, hasError)
   325  	assert.Equal(t, "100", n.String())
   326  
   327  	n, hasError = num.IntFromString("-100", 10)
   328  	assert.False(t, hasError)
   329  	assert.Equal(t, "-100", n.String())
   330  
   331  	n, hasError = num.IntFromString("0", 10)
   332  	assert.False(t, hasError)
   333  	assert.Equal(t, "0", n.String())
   334  
   335  	n, hasError = num.IntFromString("1000000000000000000000000000000000000000000000000000000000000000000000000000000", 10)
   336  	assert.True(t, hasError)
   337  	assert.Equal(t, "0", n.String())
   338  
   339  	n, hasError = num.IntFromString("-1000000000000000000000000000000000000000000000000000000000000000000000000000000", 10)
   340  	assert.True(t, hasError)
   341  	assert.Equal(t, "0", n.String())
   342  
   343  	n, hasError = num.IntFromString("not a number", 10)
   344  	assert.True(t, hasError)
   345  	assert.Equal(t, "0", n.String())
   346  }