go.starlark.net@v0.0.0-20231101134539-556fd59b42f6/starlark/testdata/int.star (about)

     1  # Tests of Starlark 'int'
     2  
     3  load("assert.star", "assert")
     4  
     5  # basic arithmetic
     6  assert.eq(0 - 1, -1)
     7  assert.eq(0 + 1, +1)
     8  assert.eq(1 + 1, 2)
     9  assert.eq(5 + 7, 12)
    10  assert.eq(5 * 7, 35)
    11  assert.eq(5 - 7, -2)
    12  
    13  # int boundaries
    14  maxint64 = (1 << 63) - 1
    15  minint64 = -1 << 63
    16  maxint32 = (1 << 31) - 1
    17  minint32 = -1 << 31
    18  assert.eq(maxint64, 9223372036854775807)
    19  assert.eq(minint64, -9223372036854775808)
    20  assert.eq(maxint32, 2147483647)
    21  assert.eq(minint32, -2147483648)
    22  
    23  # truth
    24  def truth():
    25      assert.true(not 0)
    26      for m in [1, maxint32]:  # Test small/big ranges
    27          assert.true(123 * m)
    28          assert.true(-1 * m)
    29  
    30  truth()
    31  
    32  # floored division
    33  # (For real division, see float.star.)
    34  def division():
    35      for m in [1, maxint32]:  # Test small/big ranges
    36          assert.eq((100 * m) // (7 * m), 14)
    37          assert.eq((100 * m) // (-7 * m), -15)
    38          assert.eq((-100 * m) // (7 * m), -15)  # NB: different from Go/Java
    39          assert.eq((-100 * m) // (-7 * m), 14)  # NB: different from Go/Java
    40          assert.eq((98 * m) // (7 * m), 14)
    41          assert.eq((98 * m) // (-7 * m), -14)
    42          assert.eq((-98 * m) // (7 * m), -14)
    43          assert.eq((-98 * m) // (-7 * m), 14)
    44  
    45  division()
    46  
    47  # remainder
    48  def remainder():
    49      for m in [1, maxint32]:  # Test small/big ranges
    50          assert.eq((100 * m) % (7 * m), 2 * m)
    51          assert.eq((100 * m) % (-7 * m), -5 * m)  # NB: different from Go/Java
    52          assert.eq((-100 * m) % (7 * m), 5 * m)  # NB: different from Go/Java
    53          assert.eq((-100 * m) % (-7 * m), -2 * m)
    54          assert.eq((98 * m) % (7 * m), 0)
    55          assert.eq((98 * m) % (-7 * m), 0)
    56          assert.eq((-98 * m) % (7 * m), 0)
    57          assert.eq((-98 * m) % (-7 * m), 0)
    58  
    59  remainder()
    60  
    61  # compound assignment
    62  def compound():
    63      x = 1
    64      x += 1
    65      assert.eq(x, 2)
    66      x -= 3
    67      assert.eq(x, -1)
    68      x *= 39
    69      assert.eq(x, -39)
    70      x //= 4
    71      assert.eq(x, -10)
    72      x /= -2
    73      assert.eq(x, 5)
    74      x %= 3
    75      assert.eq(x, 2)
    76  
    77      x = 2
    78      x &= 1
    79      assert.eq(x, 0)
    80      x |= 2
    81      assert.eq(x, 2)
    82      x ^= 3
    83      assert.eq(x, 1)
    84      x <<= 2
    85      assert.eq(x, 4)
    86      x >>= 2
    87      assert.eq(x, 1)
    88  
    89  compound()
    90  
    91  # int conversion
    92  # See float.star for float-to-int conversions.
    93  # We follow Python 3 here, but I can't see the method in its madness.
    94  # int from bool/int/float
    95  assert.fails(int, "missing argument")  # int()
    96  assert.eq(int(False), 0)
    97  assert.eq(int(True), 1)
    98  assert.eq(int(3), 3)
    99  assert.eq(int(3.1), 3)
   100  assert.fails(lambda: int(3, base = 10), "non-string with explicit base")
   101  assert.fails(lambda: int(True, 10), "non-string with explicit base")
   102  
   103  # int from string, base implicitly 10
   104  assert.eq(int("100000000000000000000"), 10000000000 * 10000000000)
   105  assert.eq(int("-100000000000000000000"), -10000000000 * 10000000000)
   106  assert.eq(int("123"), 123)
   107  assert.eq(int("-123"), -123)
   108  assert.eq(int("0123"), 123)  # not octal
   109  assert.eq(int("-0123"), -123)
   110  assert.fails(lambda: int("0x12"), "invalid literal with base 10")
   111  assert.fails(lambda: int("-0x12"), "invalid literal with base 10")
   112  assert.fails(lambda: int("0o123"), "invalid literal.*base 10")
   113  assert.fails(lambda: int("-0o123"), "invalid literal.*base 10")
   114  
   115  # int from string, explicit base
   116  assert.eq(int("0"), 0)
   117  assert.eq(int("00"), 0)
   118  assert.eq(int("0", base = 10), 0)
   119  assert.eq(int("00", base = 10), 0)
   120  assert.eq(int("0", base = 8), 0)
   121  assert.eq(int("00", base = 8), 0)
   122  assert.eq(int("-0"), 0)
   123  assert.eq(int("-00"), 0)
   124  assert.eq(int("-0", base = 10), 0)
   125  assert.eq(int("-00", base = 10), 0)
   126  assert.eq(int("-0", base = 8), 0)
   127  assert.eq(int("-00", base = 8), 0)
   128  assert.eq(int("+0"), 0)
   129  assert.eq(int("+00"), 0)
   130  assert.eq(int("+0", base = 10), 0)
   131  assert.eq(int("+00", base = 10), 0)
   132  assert.eq(int("+0", base = 8), 0)
   133  assert.eq(int("+00", base = 8), 0)
   134  assert.eq(int("11", base = 9), 10)
   135  assert.eq(int("-11", base = 9), -10)
   136  assert.eq(int("10011", base = 2), 19)
   137  assert.eq(int("-10011", base = 2), -19)
   138  assert.eq(int("123", 8), 83)
   139  assert.eq(int("-123", 8), -83)
   140  assert.eq(int("0123", 8), 83)  # redundant zeros permitted
   141  assert.eq(int("-0123", 8), -83)
   142  assert.eq(int("00123", 8), 83)
   143  assert.eq(int("-00123", 8), -83)
   144  assert.eq(int("0o123", 8), 83)
   145  assert.eq(int("-0o123", 8), -83)
   146  assert.eq(int("123", 7), 66)  # 1*7*7 + 2*7 + 3
   147  assert.eq(int("-123", 7), -66)
   148  assert.eq(int("12", 16), 18)
   149  assert.eq(int("-12", 16), -18)
   150  assert.eq(int("0x12", 16), 18)
   151  assert.eq(int("-0x12", 16), -18)
   152  assert.eq(0x1000000000000001 * 0x1000000000000001, 0x1000000000000002000000000000001)
   153  assert.eq(int("1010", 2), 10)
   154  assert.eq(int("111111101", 2), 509)
   155  assert.eq(int("0b0101", 0), 5)
   156  assert.eq(int("0b0101", 2), 5) # prefix is redundant with explicit base
   157  assert.eq(int("0b00000", 0), 0)
   158  assert.eq(1111111111111111 * 1111111111111111, 1234567901234567654320987654321)
   159  assert.fails(lambda: int("0x123", 8), "invalid literal.*base 8")
   160  assert.fails(lambda: int("-0x123", 8), "invalid literal.*base 8")
   161  assert.fails(lambda: int("0o123", 16), "invalid literal.*base 16")
   162  assert.fails(lambda: int("-0o123", 16), "invalid literal.*base 16")
   163  assert.fails(lambda: int("0x110", 2), "invalid literal.*base 2")
   164  
   165  # Base prefix is honored only if base=0, or if the prefix matches the explicit base.
   166  # See https://github.com/google/starlark-go/issues/337
   167  assert.fails(lambda: int("0b0"), "invalid literal.*base 10")
   168  assert.eq(int("0b0", 0), 0)
   169  assert.eq(int("0b0", 2), 0)
   170  assert.eq(int("0b0", 16), 0xb0)
   171  assert.eq(int("0x0b0", 16), 0xb0)
   172  assert.eq(int("0x0b0", 0), 0xb0)
   173  assert.eq(int("0x0b0101", 16), 0x0b0101)
   174  
   175  # int from string, auto detect base
   176  assert.eq(int("123", 0), 123)
   177  assert.eq(int("+123", 0), +123)
   178  assert.eq(int("-123", 0), -123)
   179  assert.eq(int("0x12", 0), 18)
   180  assert.eq(int("+0x12", 0), +18)
   181  assert.eq(int("-0x12", 0), -18)
   182  assert.eq(int("0o123", 0), 83)
   183  assert.eq(int("+0o123", 0), +83)
   184  assert.eq(int("-0o123", 0), -83)
   185  assert.fails(lambda: int("0123", 0), "invalid literal.*base 0")  # valid in Python 2.7
   186  assert.fails(lambda: int("-0123", 0), "invalid literal.*base 0")
   187  
   188  # github.com/google/starlark-go/issues/108
   189  assert.fails(lambda: int("0Oxa", 8), "invalid literal with base 8: 0Oxa")
   190  
   191  # follow-on bugs to issue 108
   192  assert.fails(lambda: int("--4"), "invalid literal with base 10: --4")
   193  assert.fails(lambda: int("++4"), "invalid literal with base 10: \\+\\+4")
   194  assert.fails(lambda: int("+-4"), "invalid literal with base 10: \\+-4")
   195  assert.fails(lambda: int("0x-4", 16), "invalid literal with base 16: 0x-4")
   196  
   197  # bitwise union (int|int), intersection (int&int), XOR (int^int), unary not (~int),
   198  # left shift (int<<int), and right shift (int>>int).
   199  # TODO(adonovan): this is not yet in the Starlark spec,
   200  # but there is consensus that it should be.
   201  assert.eq(1 | 2, 3)
   202  assert.eq(3 | 6, 7)
   203  assert.eq((1 | 2) & (2 | 4), 2)
   204  assert.eq(1 ^ 2, 3)
   205  assert.eq(2 ^ 2, 0)
   206  assert.eq(1 | 0 ^ 1, 1)  # check | and ^ operators precedence
   207  assert.eq(~1, -2)
   208  assert.eq(~(-2), 1)
   209  assert.eq(~0, -1)
   210  assert.eq(1 << 2, 4)
   211  assert.eq(2 >> 1, 1)
   212  assert.fails(lambda: 2 << -1, "negative shift count")
   213  assert.fails(lambda: 1 << 512, "shift count too large")
   214  
   215  # comparisons
   216  # TODO(adonovan): test: < > == != etc
   217  def comparisons():
   218      for m in [1, maxint32 / 2, maxint32]:  # Test small/big ranges
   219          assert.lt(-2 * m, -1 * m)
   220          assert.lt(-1 * m, 0 * m)
   221          assert.lt(0 * m, 1 * m)
   222          assert.lt(1 * m, 2 * m)
   223          assert.true(2 * m >= 2 * m)
   224          assert.true(2 * m > 1 * m)
   225          assert.true(1 * m >= 1 * m)
   226          assert.true(1 * m > 0 * m)
   227          assert.true(0 * m >= 0 * m)
   228          assert.true(0 * m > -1 * m)
   229          assert.true(-1 * m >= -1 * m)
   230          assert.true(-1 * m > -2 * m)
   231  
   232  comparisons()
   233  
   234  # precision
   235  assert.eq(str(maxint64), "9223372036854775807")
   236  assert.eq(str(maxint64 + 1), "9223372036854775808")
   237  assert.eq(str(minint64), "-9223372036854775808")
   238  assert.eq(str(minint64 - 1), "-9223372036854775809")
   239  assert.eq(str(minint64 * minint64), "85070591730234615865843651857942052864")
   240  assert.eq(str(maxint32 + 1), "2147483648")
   241  assert.eq(str(minint32 - 1), "-2147483649")
   242  assert.eq(str(minint32 * minint32), "4611686018427387904")
   243  assert.eq(str(minint32 | maxint32), "-1")
   244  assert.eq(str(minint32 & minint32), "-2147483648")
   245  assert.eq(str(minint32 ^ maxint32), "-1")
   246  assert.eq(str(minint32 // -1), "2147483648")
   247  
   248  # string formatting
   249  assert.eq("%o %x %d" % (0o755, 0xDEADBEEF, 42), "755 deadbeef 42")
   250  nums = [-95, -1, 0, +1, +95]
   251  assert.eq(" ".join(["%o" % x for x in nums]), "-137 -1 0 1 137")
   252  assert.eq(" ".join(["%d" % x for x in nums]), "-95 -1 0 1 95")
   253  assert.eq(" ".join(["%i" % x for x in nums]), "-95 -1 0 1 95")
   254  assert.eq(" ".join(["%x" % x for x in nums]), "-5f -1 0 1 5f")
   255  assert.eq(" ".join(["%X" % x for x in nums]), "-5F -1 0 1 5F")
   256  assert.eq("%o %x %d" % (123, 123, 123), "173 7b 123")
   257  assert.eq("%o %x %d" % (123.1, 123.1, 123.1), "173 7b 123")  # non-int operands are acceptable
   258  assert.fails(lambda: "%d" % True, "cannot convert bool to int")