github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/uint256/bitwise_test.gno (about)

     1  package uint256
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  type logicOpTest struct {
     8  	name string
     9  	x    Uint
    10  	y    Uint
    11  	want Uint
    12  }
    13  
    14  func TestOr(t *testing.T) {
    15  	tests := []logicOpTest{
    16  		{
    17  			name: "all zeros",
    18  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
    19  			y:    Uint{arr: [4]uint64{0, 0, 0, 0}},
    20  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
    21  		},
    22  		{
    23  			name: "all ones",
    24  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    25  			y:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    26  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    27  		},
    28  		{
    29  			name: "mixed",
    30  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), 0, 0}},
    31  			y:    Uint{arr: [4]uint64{0, 0, ^uint64(0), ^uint64(0)}},
    32  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    33  		},
    34  		{
    35  			name: "one operand all ones",
    36  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    37  			y:    Uint{arr: [4]uint64{0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000}},
    38  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    39  		},
    40  	}
    41  
    42  	for _, tc := range tests {
    43  		t.Run(tc.name, func(t *testing.T) {
    44  			res := new(Uint).Or(&tc.x, &tc.y)
    45  			if *res != tc.want {
    46  				t.Errorf("Or(%s, %s) = %s, want %s", tc.x.ToString(), tc.y.ToString(), res.ToString(), (tc.want).ToString())
    47  			}
    48  		})
    49  	}
    50  }
    51  
    52  func TestAnd(t *testing.T) {
    53  	tests := []logicOpTest{
    54  		{
    55  			name: "all zeros",
    56  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
    57  			y:    Uint{arr: [4]uint64{0, 0, 0, 0}},
    58  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
    59  		},
    60  		{
    61  			name: "all ones",
    62  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    63  			y:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    64  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    65  		},
    66  		{
    67  			name: "mixed",
    68  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
    69  			y:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    70  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
    71  		},
    72  		{
    73  			name: "mixed 2",
    74  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    75  			y:    Uint{arr: [4]uint64{0, 0, 0, 0}},
    76  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
    77  		},
    78  		{
    79  			name: "mixed 3",
    80  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), 0, 0}},
    81  			y:    Uint{arr: [4]uint64{0, 0, ^uint64(0), ^uint64(0)}},
    82  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
    83  		},
    84  		{
    85  			name: "one operand zero",
    86  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
    87  			y:    Uint{arr: [4]uint64{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}},
    88  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
    89  		},
    90  		{
    91  			name: "one operand all ones",
    92  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
    93  			y:    Uint{arr: [4]uint64{0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000}},
    94  			want: Uint{arr: [4]uint64{0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000}},
    95  		},
    96  	}
    97  
    98  	for _, tc := range tests {
    99  		t.Run(tc.name, func(t *testing.T) {
   100  			res := new(Uint).And(&tc.x, &tc.y)
   101  			if *res != tc.want {
   102  				t.Errorf("And(%s, %s) = %s, want %s", tc.x.ToString(), tc.y.ToString(), res.ToString(), (tc.want).ToString())
   103  			}
   104  		})
   105  	}
   106  }
   107  
   108  func TestNot(t *testing.T) {
   109  	tests := []struct {
   110  		name string
   111  		x    Uint
   112  		want Uint
   113  	}{
   114  		{
   115  			name: "all zeros",
   116  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   117  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   118  		},
   119  		{
   120  			name: "all ones",
   121  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   122  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
   123  		},
   124  		{
   125  			name: "mixed",
   126  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), 0, 0}},
   127  			want: Uint{arr: [4]uint64{0, 0, ^uint64(0), ^uint64(0)}},
   128  		},
   129  	}
   130  
   131  	for _, tc := range tests {
   132  		t.Run(tc.name, func(t *testing.T) {
   133  			res := new(Uint).Not(&tc.x)
   134  			if *res != tc.want {
   135  				t.Errorf("Not(%s) = %s, want %s", tc.x.ToString(), res.ToString(), (tc.want).ToString())
   136  			}
   137  		})
   138  	}
   139  }
   140  
   141  func TestAndNot(t *testing.T) {
   142  	tests := []logicOpTest{
   143  		{
   144  			name: "all zeros",
   145  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   146  			y:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   147  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
   148  		},
   149  		{
   150  			name: "all ones",
   151  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   152  			y:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   153  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
   154  		},
   155  		{
   156  			name: "mixed",
   157  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   158  			y:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   159  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
   160  		},
   161  		{
   162  			name: "mixed 2",
   163  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   164  			y:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   165  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   166  		},
   167  		{
   168  			name: "mixed 3",
   169  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), 0, 0}},
   170  			y:    Uint{arr: [4]uint64{0, 0, ^uint64(0), ^uint64(0)}},
   171  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), 0, 0}},
   172  		},
   173  		{
   174  			name: "one operand zero",
   175  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   176  			y:    Uint{arr: [4]uint64{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}},
   177  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
   178  		},
   179  		{
   180  			name: "one operand all ones",
   181  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   182  			y:    Uint{arr: [4]uint64{0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000}},
   183  			want: Uint{arr: [4]uint64{0xAAAAAAAAAAAAAAAA, 0x5555555555555555, 0x0000000000000000, ^uint64(0)}},
   184  		},
   185  	}
   186  
   187  	for _, tc := range tests {
   188  		t.Run(tc.name, func(t *testing.T) {
   189  			res := new(Uint).AndNot(&tc.x, &tc.y)
   190  			if *res != tc.want {
   191  				t.Errorf("AndNot(%s, %s) = %s, want %s", tc.x.ToString(), tc.y.ToString(), res.ToString(), (tc.want).ToString())
   192  			}
   193  		})
   194  	}
   195  }
   196  
   197  func TestXor(t *testing.T) {
   198  	tests := []logicOpTest{
   199  		{
   200  			name: "all zeros",
   201  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   202  			y:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   203  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
   204  		},
   205  		{
   206  			name: "all ones",
   207  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   208  			y:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   209  			want: Uint{arr: [4]uint64{0, 0, 0, 0}},
   210  		},
   211  		{
   212  			name: "mixed",
   213  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   214  			y:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   215  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   216  		},
   217  		{
   218  			name: "mixed 2",
   219  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   220  			y:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   221  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   222  		},
   223  		{
   224  			name: "mixed 3",
   225  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), 0, 0}},
   226  			y:    Uint{arr: [4]uint64{0, 0, ^uint64(0), ^uint64(0)}},
   227  			want: Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   228  		},
   229  		{
   230  			name: "one operand zero",
   231  			x:    Uint{arr: [4]uint64{0, 0, 0, 0}},
   232  			y:    Uint{arr: [4]uint64{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}},
   233  			want: Uint{arr: [4]uint64{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}},
   234  		},
   235  		{
   236  			name: "one operand all ones",
   237  			x:    Uint{arr: [4]uint64{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)}},
   238  			y:    Uint{arr: [4]uint64{0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000}},
   239  			want: Uint{arr: [4]uint64{0xAAAAAAAAAAAAAAAA, 0x5555555555555555, 0x0000000000000000, ^uint64(0)}},
   240  		},
   241  	}
   242  
   243  	for _, tc := range tests {
   244  		t.Run(tc.name, func(t *testing.T) {
   245  			res := new(Uint).Xor(&tc.x, &tc.y)
   246  			if *res != tc.want {
   247  				t.Errorf("Xor(%s, %s) = %s, want %s", tc.x.ToString(), tc.y.ToString(), res.ToString(), (tc.want).ToString())
   248  			}
   249  		})
   250  	}
   251  }
   252  
   253  func TestLsh(t *testing.T) {
   254  	tests := []struct {
   255  		x    string
   256  		y    uint
   257  		want string
   258  	}{
   259  		{"0", 0, "0"},
   260  		{"0", 1, "0"},
   261  		{"0", 64, "0"},
   262  		{"1", 0, "1"},
   263  		{"1", 1, "2"},
   264  		{"1", 64, "18446744073709551616"},
   265  		{"1", 128, "340282366920938463463374607431768211456"},
   266  		{"1", 192, "6277101735386680763835789423207666416102355444464034512896"},
   267  		{"1", 255, "57896044618658097711785492504343953926634992332820282019728792003956564819968"},
   268  		{"1", 256, "0"},
   269  		{"31337", 0, "31337"},
   270  		{"31337", 1, "62674"},
   271  		{"31337", 64, "578065619037836218990592"},
   272  		{"31337", 128, "10663428532201448629551770073089320442396672"},
   273  		{"31337", 192, "196705537081812415096322133155058642481399512563169449530621952"},
   274  		{"31337", 193, "393411074163624830192644266310117284962799025126338899061243904"},
   275  		{"31337", 255, "57896044618658097711785492504343953926634992332820282019728792003956564819968"},
   276  		{"31337", 256, "0"},
   277  	}
   278  
   279  	for _, tc := range tests {
   280  		x, err := FromDecimal(tc.x)
   281  		if err != nil {
   282  			t.Error(err)
   283  			continue
   284  		}
   285  
   286  		want, err := FromDecimal(tc.want)
   287  		if err != nil {
   288  			t.Error(err)
   289  			continue
   290  		}
   291  
   292  		got := &Uint{}
   293  		got.Lsh(x, tc.y)
   294  
   295  		if got.Neq(want) {
   296  			t.Errorf("Lsh(%s, %d) = %s, want %s", tc.x, tc.y, got.ToString(), want.ToString())
   297  		}
   298  	}
   299  }
   300  
   301  func TestRsh(t *testing.T) {
   302  	tests := []struct {
   303  		x    string
   304  		y    uint
   305  		want string
   306  	}{
   307  		{"0", 0, "0"},
   308  		{"0", 1, "0"},
   309  		{"0", 64, "0"},
   310  		{"1", 0, "1"},
   311  		{"1", 1, "0"},
   312  		{"1", 64, "0"},
   313  		{"1", 128, "0"},
   314  		{"1", 192, "0"},
   315  		{"1", 255, "0"},
   316  		{"57896044618658097711785492504343953926634992332820282019728792003956564819968", 255, "1"},
   317  		{"6277101735386680763835789423207666416102355444464034512896", 192, "1"},
   318  		{"340282366920938463463374607431768211456", 128, "1"},
   319  		{"18446744073709551616", 64, "1"},
   320  		{"393411074163624830192644266310117284962799025126338899061243904", 193, "31337"},
   321  		{"196705537081812415096322133155058642481399512563169449530621952", 192, "31337"},
   322  		{"10663428532201448629551770073089320442396672", 128, "31337"},
   323  		{"578065619037836218990592", 64, "31337"},
   324  	}
   325  
   326  	for _, tc := range tests {
   327  		x, err := FromDecimal(tc.x)
   328  		if err != nil {
   329  			t.Error(err)
   330  			continue
   331  		}
   332  
   333  		want, err := FromDecimal(tc.want)
   334  		if err != nil {
   335  			t.Error(err)
   336  			continue
   337  		}
   338  
   339  		got := &Uint{}
   340  		got.Rsh(x, tc.y)
   341  
   342  		if got.Neq(want) {
   343  			t.Errorf("Rsh(%s, %d) = %s, want %s", tc.x, tc.y, got.ToString(), want.ToString())
   344  		}
   345  	}
   346  }