MPZ Functionality
=================

Testing of mpz functionality is split into multiple files.

    test_mpz.txt
        Test basic functionality and stuff not covered anywhere else.

    test_mpz_functions.txt
        Test mpz functions, including error messages.

    test_mpz_io.txt
        Test input/output and formating.

    test_mpz_comp.txt
        Test comparisons.

>>> import gmpy2 as G
>>> from gmpy2 import mpz, mpq, mpfr, mpc
>>> from supportclasses import *
>>> from decimal import Decimal as D
>>> from fractions import Fraction as F
>>> a = mpz(123)
>>> b = mpz(456)
>>> c = 12345678901234567890
>>> ctx = gmpy2.get_context()

Test elementary operations
==========================

Test addition
-------------

>>> a+1
mpz(124)
>>> a+(-1)
mpz(122)
>>> 1+a
mpz(124)
>>> (-1)+a
mpz(122)
>>> a+b
mpz(579)
>>> b+a
mpz(579)
>>> a+'b'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'mpz' and 'str'
>>> 'b'+a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ** message detail varies **
>>> print(a+c)
12345678901234568013
>>> print(c+a)
12345678901234568013


Test subtraction
----------------

>>> a-1
mpz(122)
>>> a-(-1)
mpz(124)
>>> 1-a
mpz(-122)
>>> (-1)-a
mpz(-124)
>>> a-b
mpz(-333)
>>> b-a
mpz(333)
>>> a-'b'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'mpz' and 'str'
>>> 'b'-a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ** message detail varies **
>>> print(a-c)
-12345678901234567767
>>> print(c-a)
12345678901234567767

Test multiplication
-------------------

>>> a*b
mpz(56088)
>>> b*a
mpz(56088)
>>> a*0
mpz(0)
>>> 0*a
mpz(0)
>>> a*123
mpz(15129)
>>> 123*a
mpz(15129)
>>> print(a*c)
1518518504851851850470
>>> print(c*a)
1518518504851851850470
>>> a*'b'
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
>>> 'b'*a
'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'

Test division
-------------

>>> a//b
mpz(0)
>>> a/b
mpfr('0.26973684210526316')
>>> gmpy2.div(a, b)
mpfr('0.26973684210526316')
>>> ctx.div(a, b)
mpfr('0.26973684210526316')
>>> b//a
mpz(3)
>>> b/a
mpfr('3.7073170731707319')
>>> (a*b)//b
mpz(123)
>>> (a*b)//a
mpz(456)
>>> a//0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> a/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> a/0.0
mpfr('inf')
>>> print(c//a)
100371373180768844
>>> a**10//c
mpz(64)
>>> a / z
mpfr('61.5')
>>> a // z
mpz(61)
>>> ctx.div(a, b, 5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: div() requires 2 arguments.
>>> ctx.div(a, 'str')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: div() argument type not supported
>>> a / 'str'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'mpz' and 'str'
>>> 1
1
>>> with gmpy2.local_context(rational_division=True):
...     print(mpz(1)/mpz(2))
...
1/2

Test modulo
-----------

>>> a % b
mpz(123)
>>> b % a
mpz(87)
>>> gmpy2.mod(b, a)
mpz(87)
>>> ctx.mod(b, a)
mpz(87)
>>> a % z
mpz(1)
>>> divmod(a,b)
(mpz(0), mpz(123))
>>> divmod(b,a)
(mpz(3), mpz(87))
>>> a % mpz(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> divmod(a,0)
Traceback (most recent call last):
  ...
ZeroDivisionError: division or modulo by zero
>>> divmod(a, mpz(0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> divmod(123, mpz(0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> a % 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> 14 % mpz(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> gmpy2.mod(14, mpz(0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> gmpy2.mod(124, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> gmpy2.mod(b, mpz(0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> ctx.mod(b, mpz(0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division or modulo by zero
>>> gmpy2.mod(124, 'str')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: mod() argument type not supported
>>> a % 'str'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for %: 'mpz' and 'str'
>>> gmpy2.mod(124, mpz(5))
mpz(4)
>>> divmod(b,123)
(mpz(3), mpz(87))
>>> divmod(a,c)
(mpz(0), mpz(123))
>>> divmod(a,int(c))
(mpz(0), mpz(123))
>>> print("%s %s" % divmod(a*(c-1),c))
122 12345678901234567767
>>> print("%s %s" % divmod(a*(c-1),int(c)))
122 12345678901234567767
>>> divmod(a*(c-1),-c)
(mpz(-123), mpz(-123))
>>> divmod(a*(c-1),-int(c))
(mpz(-123), mpz(-123))
>>> print("%s %s" % divmod(int(a*(c-1)),-int(c)))
-123 -123
>>> z % mpq(1,2)
mpq(0,1)
>>> a % mpq(2,3)
mpq(1,3)

Test miscellaneous
------------------

>>> a+True
mpz(124)
>>> a+False
mpz(123)
>>> a*False
mpz(0)
>>> a//True
mpz(123)
>>> abs(-a) == a
True
>>> print(pow(a,10))
792594609605189126649
>>> pow(a,7,b)
mpz(99)
>>> G.sign(b-a)
1
>>> G.sign(b-b)
0
>>> G.sign(a-b)
-1
>>> G.sign(a)
1
>>> G.sign(-a)
-1
>>> z=b-b; G.sign(z)
0

Test mpz.__index__
------------------

>>> range(333)[a]
123
>>> range(333)[b]
Traceback (innermost last):
  ...
IndexError: range object index out of range
>>> 1
1

Test operations involving NaN/Inf
---------------------------------

>>> a + float('Inf')
mpfr('inf')
>>> float('Inf') + a
mpfr('inf')
>>> a + float('-Inf')
mpfr('-inf')
>>> float('-Inf') + a
mpfr('-inf')
>>> a + float('nan')
mpfr('nan')
>>> float('nan') + a
mpfr('nan')

>>> a - float('Inf')
mpfr('-inf')
>>> float('Inf') - a
mpfr('inf')
>>> a - float('-Inf')
mpfr('inf')
>>> float('-Inf') - a
mpfr('-inf')
>>> a - float('nan')
mpfr('nan')
>>> float('nan') - a
mpfr('nan')

>>> a * float('Inf')
mpfr('inf')
>>> float('Inf') * a
mpfr('inf')
>>> a * float('-Inf')
mpfr('-inf')
>>> float('-Inf') * a
mpfr('-inf')
>>> -a * float('Inf')
mpfr('-inf')
>>> float('Inf') * -a
mpfr('-inf')
>>> -a * float('-Inf')
mpfr('inf')
>>> float('-Inf') * -a
mpfr('inf')
>>> a * float('nan')
mpfr('nan')
>>> float('nan') * a
mpfr('nan')
>>> G.mpz(0) * float('Inf')
mpfr('nan')
>>> G.mpz(0) * float('-Inf')
mpfr('nan')
>>> float('Inf') * G.mpz(0)
mpfr('nan')
>>> float('-Inf') * G.mpz(0)
mpfr('nan')
>>> a / float('Inf')
mpfr('0.0')
>>> -a / float('Inf')
mpfr('-0.0')
>>> float('Inf') / a
mpfr('inf')
>>> float('Inf') / -a
mpfr('-inf')
>>> a / float('-Inf')
mpfr('-0.0')
>>> -a / float('-Inf')
mpfr('0.0')
>>> float('-Inf') / a
mpfr('-inf')
>>> float('-Inf') / -a
mpfr('inf')
>>> a / float('nan')
mpfr('nan')
>>> float('nan') / a
mpfr('nan')
>>> float('nan') / G.mpz(0)
mpfr('nan')
>>> float('nan') / G.mpz(0)
mpfr('nan')

>>> a - mpfr('Inf')
mpfr('-inf')
>>> mpfr('Inf') - a
mpfr('inf')
>>> a - mpfr('-Inf')
mpfr('inf')
>>> mpfr('-Inf') - a
mpfr('-inf')
>>> a - mpfr('nan')
mpfr('nan')
>>> mpfr('nan') - a
mpfr('nan')
>>> a * mpfr('Inf')
mpfr('inf')
>>> mpfr('Inf') * a
mpfr('inf')
>>> a * mpfr('-Inf')
mpfr('-inf')
>>> mpfr('-Inf') * a
mpfr('-inf')
>>> -a * mpfr('Inf')
mpfr('-inf')
>>> mpfr('Inf') * -a
mpfr('-inf')
>>> -a * mpfr('-Inf')
mpfr('inf')
>>> mpfr('-Inf') * -a
mpfr('inf')
>>> a * mpfr('nan')
mpfr('nan')
>>> mpfr('nan') * a
mpfr('nan')
>>> G.mpz(0) * mpfr('Inf')
mpfr('nan')
>>> G.mpz(0) * mpfr('-Inf')
mpfr('nan')
>>> mpfr('Inf') * G.mpz(0)
mpfr('nan')
>>> mpfr('-Inf') * G.mpz(0)
mpfr('nan')
>>> a / mpfr('Inf')
mpfr('0.0')
>>> -a / mpfr('Inf')
mpfr('-0.0')
>>> mpfr('Inf') / a
mpfr('inf')
>>> mpfr('Inf') / -a
mpfr('-inf')
>>> a / mpfr('-Inf')
mpfr('-0.0')
>>> -a / mpfr('-Inf')
mpfr('0.0')
>>> mpfr('-Inf') / a
mpfr('-inf')
>>> mpfr('-Inf') / -a
mpfr('inf')
>>> a / mpfr('nan')
mpfr('nan')
>>> mpfr('nan') / a
mpfr('nan')
>>> mpfr('nan') / G.mpz(0)
mpfr('nan')
>>> mpfr('nan') / G.mpz(0)
mpfr('nan')

>>> divmod(a, mpfr('Inf'))
(mpfr('0.0'), mpfr('123.0'))
>>> divmod(a, mpfr('-Inf'))
(mpfr('-1.0'), mpfr('-inf'))
>>> divmod(-a, mpfr('Inf'))
(mpfr('-1.0'), mpfr('inf'))
>>> divmod(-a, mpfr('-Inf'))
(mpfr('0.0'), mpfr('-123.0'))
>>> divmod(a, mpfr('nan'))
(mpfr('nan'), mpfr('nan'))
>>> divmod(-a, mpfr('nan'))
(mpfr('nan'), mpfr('nan'))
>>> divmod(G.mpz(0), mpfr('Inf'))
(mpfr('0.0'), mpfr('0.0'))
>>> divmod(G.mpz(0), mpfr('-Inf'))
(mpfr('-0.0'), mpfr('-0.0'))
>>> divmod(G.mpz(0), mpfr('nan'))
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('Inf'), a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('-Inf'), a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('Inf'), -a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('-Inf'), -a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('nan'), a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('nan'), -a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('Inf'), G.mpz(0))
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('-Inf'), G.mpz(0))
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('nan'), G.mpz(0))
(mpfr('nan'), mpfr('nan'))

>>> divmod(a, mpfr('Inf'))
(mpfr('0.0'), mpfr('123.0'))
>>> divmod(a, mpfr('-Inf'))
(mpfr('-1.0'), mpfr('-inf'))
>>> divmod(-a, mpfr('Inf'))
(mpfr('-1.0'), mpfr('inf'))
>>> divmod(-a, mpfr('-Inf'))
(mpfr('0.0'), mpfr('-123.0'))
>>> divmod(a, mpfr('nan'))
(mpfr('nan'), mpfr('nan'))
>>> divmod(-a, mpfr('nan'))
(mpfr('nan'), mpfr('nan'))
>>> divmod(G.mpz(0), mpfr('Inf'))
(mpfr('0.0'), mpfr('0.0'))
>>> divmod(G.mpz(0), mpfr('-Inf'))
(mpfr('-0.0'), mpfr('-0.0'))
>>> divmod(G.mpz(0), mpfr('nan'))
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('Inf'), a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('-Inf'), a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('Inf'), -a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('-Inf'), -a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('nan'), a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('nan'), -a)
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('Inf'), G.mpz(0))
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('-Inf'), G.mpz(0))
(mpfr('nan'), mpfr('nan'))
>>> divmod(mpfr('nan'), G.mpz(0))
(mpfr('nan'), mpfr('nan'))

Test bit operations
-------------------

>>> ~a
mpz(-124)
>>> a&b
mpz(72)
>>> a&int(b)
mpz(72)
>>> int(a)&b
mpz(72)
>>> a|b
mpz(507)
>>> a|int(b)
mpz(507)
>>> int(a)|b
mpz(507)
>>> a^b
mpz(435)
>>> a^int(b)
mpz(435)
>>> int(a)^b
mpz(435)
>>> a<<1
mpz(246)
>>> int(a)<<mpz(1)
mpz(246)
>>> a>>1
mpz(61)
>>> int(a)>>mpz(1)
mpz(61)
>>> a<<-1
Traceback (innermost last):
  ...
OverflowError: can't convert negative value to unsigned long
>>> a>>-2
Traceback (innermost last):
  ...
OverflowError: can't convert negative value to unsigned long
>>> a<<0
mpz(123)
>>> a>>0
mpz(123)
>>> "a" << a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot convert object to mpz
>>> "a" >> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot convert object to mpz
>>> a&mpq(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot convert object to mpz
>>> a|mpq(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot convert object to mpz
>>> a^mpq(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot convert object to mpz

Test conversions
----------------

>>> int(G.mpz(-3))
-3

Test Number Protocol
--------------------

>>> a.numerator
mpz(123)
>>> a.denominator
mpz(1)
>>> a.real
mpz(123)
>>> a.imag
mpz(0)
>>> a.conjugate()
mpz(123)

Sequence Protocol
-----------------

>>> a = mpz(10)
>>> a[1]
1
>>> a[-1]
1
>>> a[-2]
0
>>> a[0:2]
mpz(2)
>>> a[0:3]
mpz(2)
>>> a[0:3:-1]
mpz(0)
>>> a[111111111111111111111]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: argument too large to convert to an index
>>> a["spam"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bit positions must be integers
