github.com/k14s/starlark-go@v0.0.0-20200720175618-3a5c849cc368/starlark/int_test.go (about)

     1  // Copyright 2017 The Bazel Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package starlark
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  	"math/big"
    11  	"testing"
    12  )
    13  
    14  // TestIntOpts exercises integer arithmetic, especially at the boundaries.
    15  func TestIntOpts(t *testing.T) {
    16  	f := MakeInt64
    17  	left, right := big.NewInt(math.MinInt32), big.NewInt(math.MaxInt32)
    18  
    19  	for i, test := range []struct {
    20  		val  Int
    21  		want string
    22  	}{
    23  		// Add
    24  		{f(math.MaxInt32).Add(f(1)), "80000000"},
    25  		{f(math.MinInt32).Add(f(-1)), "-80000001"},
    26  		// Mul
    27  		{f(math.MaxInt32).Mul(f(math.MaxInt32)), "3fffffff00000001"},
    28  		{f(math.MinInt32).Mul(f(math.MinInt32)), "4000000000000000"},
    29  		{f(math.MaxUint32).Mul(f(math.MaxUint32)), "fffffffe00000001"},
    30  		{f(math.MinInt32).Mul(f(-1)), "80000000"},
    31  		// Div
    32  		{f(math.MinInt32).Div(f(-1)), "80000000"},
    33  		{f(1 << 31).Div(f(2)), "40000000"},
    34  		// And
    35  		{f(math.MaxInt32).And(f(math.MaxInt32)), "7fffffff"},
    36  		{f(math.MinInt32).And(f(math.MinInt32)), "-80000000"},
    37  		{f(1 << 33).And(f(1 << 32)), "0"},
    38  		// Mod
    39  		{f(1 << 32).Mod(f(2)), "0"},
    40  		// Or
    41  		{f(1 << 32).Or(f(0)), "100000000"},
    42  		{f(math.MaxInt32).Or(f(0)), "7fffffff"},
    43  		{f(math.MaxUint32).Or(f(0)), "ffffffff"},
    44  		{f(math.MinInt32).Or(f(math.MinInt32)), "-80000000"},
    45  		// Xor
    46  		{f(math.MinInt32).Xor(f(-1)), "7fffffff"},
    47  		// Not
    48  		{f(math.MinInt32).Not(), "7fffffff"},
    49  		{f(math.MaxInt32).Not(), "-80000000"},
    50  		// Shift
    51  		{f(1).Lsh(31), "80000000"},
    52  		{f(1).Lsh(32), "100000000"},
    53  		{f(math.MaxInt32 + 1).Rsh(1), "40000000"},
    54  		{f(math.MinInt32 * 2).Rsh(1), "-80000000"},
    55  	} {
    56  		if got := fmt.Sprintf("%x", test.val); got != test.want {
    57  			t.Errorf("%d equals %s, want %s", i, got, test.want)
    58  		}
    59  		if test.val.small < math.MinInt32 || math.MaxInt32 < test.val.small {
    60  			t.Errorf("expected big, %d %s", i, test.val)
    61  		}
    62  		if test.val.big == nil {
    63  			continue
    64  		}
    65  		if test.val.small != 0 {
    66  			t.Errorf("expected 0 small, %d %s with %d", i, test.val, test.val.small)
    67  		}
    68  		if b := test.val.big; b.Cmp(left) >= 0 && b.Cmp(right) <= 0 {
    69  			t.Errorf("expected small, %d %s", i, test.val)
    70  		}
    71  	}
    72  }