Skip to content

Commit db8950c

Browse files
committed
py: int: tests for **, <<, >> and fixes
1 parent 313e2cb commit db8950c

File tree

2 files changed

+117
-7
lines changed

2 files changed

+117
-7
lines changed

py/bigint.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,26 @@ func (a *BigInt) M__rdivmod__(other Object) (Object, Object, error) {
276276
return NotImplemented, NotImplemented, nil
277277
}
278278

279+
// Raise to the power a**b or if m != nil, a**b mod m
280+
func (a *BigInt) pow(b, m *BigInt) (Object, error) {
281+
// -ve power => make float
282+
if (*big.Int)(b).Sign() < 0 {
283+
if m != nil {
284+
return nil, ExceptionNewf(TypeError, "pow() 2nd argument cannot be negative when 3rd argument specified")
285+
}
286+
fa, err := a.Float()
287+
if err != nil {
288+
return nil, err
289+
}
290+
fb, err := b.Float()
291+
if err != nil {
292+
return nil, err
293+
}
294+
return fa.M__pow__(fb, None)
295+
}
296+
return (*BigInt)(new(big.Int).Exp((*big.Int)(a), (*big.Int)(b), (*big.Int)(m))).MaybeInt(), nil
297+
}
298+
279299
func (a *BigInt) M__pow__(other, modulus Object) (Object, error) {
280300
var m *BigInt
281301
if modulus != None {
@@ -285,14 +305,14 @@ func (a *BigInt) M__pow__(other, modulus Object) (Object, error) {
285305
}
286306
}
287307
if b, ok := convertToBigInt(other); ok {
288-
return (*BigInt)(new(big.Int).Exp((*big.Int)(a), (*big.Int)(b), (*big.Int)(m))).MaybeInt(), nil
308+
return a.pow(b, m)
289309
}
290310
return NotImplemented, nil
291311
}
292312

293313
func (a *BigInt) M__rpow__(other Object) (Object, error) {
294314
if b, ok := convertToBigInt(other); ok {
295-
return (*BigInt)(new(big.Int).Exp((*big.Int)(b), (*big.Int)(a), nil)).MaybeInt(), nil
315+
return b.pow(a, nil)
296316
}
297317
return NotImplemented, nil
298318
}

py/tests/int.py

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -454,14 +454,104 @@ def approxEqual(a, b):
454454
a ^= -236051837221964566609479775048
455455
assert a == 737915270162409905551579208985
456456

457+
doc="<< and >>"
458+
assert (-1 << 10) == -1024
459+
assert (-1 >> 10) == -1
460+
assert (3 << 10) == 3072
461+
assert (3 >> 10) == 0
462+
assert (-1 << 100) == -1267650600228229401496703205376
463+
assert (-1267650600228229401496703205376 >> 50) == -1125899906842624
464+
assert (-1267650600228229401496703205376 >> 90) == -1024
465+
assert (1 << 100) == 1267650600228229401496703205376
466+
assert (1267650600228229401496703205376 >> 50) == 1125899906842624
467+
assert (1267650600228229401496703205376 >> 90) == 1024
468+
try:
469+
1 << 100000000000000000000000000000000000
470+
except OverflowError:
471+
pass
472+
else:
473+
assert False, "Overflow error not raised"
474+
475+
doc="<<= and >>="
476+
a = -1
477+
a <<= 10
478+
assert a == -1024
479+
a = -1
480+
a >>= 10
481+
assert a == -1
482+
a = 3
483+
a <<= 10
484+
assert a == 3072
485+
a = 3
486+
a >>= 10
487+
assert a == 0
488+
a = -1
489+
a <<= 100
490+
assert a == -1267650600228229401496703205376
491+
a = -1267650600228229401496703205376
492+
a >>= 50
493+
assert a == -1125899906842624
494+
a = -1267650600228229401496703205376
495+
a >>= 90
496+
assert a == -1024
497+
a = 1
498+
a <<= 100
499+
assert a == 1267650600228229401496703205376
500+
a = 1267650600228229401496703205376
501+
a >>= 50
502+
assert a == 1125899906842624
503+
a = 1267650600228229401496703205376
504+
a >>= 90
505+
assert a == 1024
506+
try:
507+
a = 1
508+
a <<= 100000000000000000000000000000000000
509+
except OverflowError:
510+
pass
511+
else:
512+
assert False, "Overflow error not raised"
513+
514+
doc="**"
515+
assert (2**10) == 1024
516+
assert ((-2)**10) == 1024
517+
approxEqual(2**(-10), 0.0009765625)
518+
approxEqual((-2)**(-10), 0.0009765625)
519+
assert (3**100) == 515377520732011331036461129765621272702107522001
520+
approxEqual(515377520732011331036461129765621272702107522001**(-1), 1.9403252174826328e-48)
521+
assert ((-1)**100000000000000000000) == 1
522+
assert ((-1)**100000000000000000001) == -1
523+
524+
doc="**="
525+
a = 2
526+
a **= 10
527+
assert a == 1024
528+
a = -2
529+
a **= 10
530+
assert a == 1024
531+
a = 2
532+
a **= -10
533+
approxEqual(a, 0.0009765625)
534+
a = -2
535+
a **= -10
536+
approxEqual(a, 0.0009765625)
537+
538+
a = 3
539+
a **= 100
540+
assert a == 515377520732011331036461129765621272702107522001
541+
a = 515377520732011331036461129765621272702107522001
542+
a **= -1
543+
approxEqual(a, 1.9403252174826328e-48)
544+
a = -1
545+
a **= 100000000000000000000
546+
assert a == 1
547+
a = -1
548+
a **= 100000000000000000001
549+
assert a == -1
550+
457551
# FIXME
458-
# powmod
552+
# pow
459553
# divmod
460-
# <<
461-
# >>
462554
# round
463-
# **
464-
# **=
465555

466556
doc="finished"
467557

0 commit comments

Comments
 (0)