aboutsummaryrefslogtreecommitdiffstats
path: root/python
Commit message (Collapse)AuthorAgeFilesLines
* python: refine the result of set_option.Tristan Gingold2019-06-261-1/+2
|
* python: add __init__.py files.Tristan Gingold2019-06-252-0/+0
|
* libghdl: fix support for non-posix OS.Tristan Gingold2019-06-241-1/+2
|
* python: add version.py, check it in configure.Tristan Gingold2019-06-243-21/+4
|
* libraries.py: add more bindings.Tristan Gingold2019-06-241-0/+4
|
* setup.py: rework version extraction.Tristan Gingold2019-06-212-3/+37
|
* libghdl: just put the version in config.pyTristan Gingold2019-06-201-23/+33
|
* libghdl/__init__.py: rework prefix search.Tristan Gingold2019-06-201-23/+55
|
* Move setup.pyTristan Gingold2019-06-201-2/+2
|
* fix: move src/xtools to python/xtools (#846)1138-4EB2019-06-171-0/+929
| | | | | | * fix: move src/xtools to python/xtools * fix Makefiles affected by xtools and pnodes being moved
* Rework libghdl build/install procedure (#840)1138-4EB2019-06-1727-0/+5864
* feat(libghdl): add libghdl_pkg.py, add option to generate libghdl-py.tgz with dist/travis/build.sh * libghdl*.so is now part of GHDL * move python sources to python/libghdl and python/pnodes * rename src/vhdl/python to src/vhdl/libghdl * add generation of tarball for libghdl-py to the makefile * deprecate --enable-python and --disable-python * add configuration option --disable-libghdl * feat(python/libghdl): add support for LIBGHDL_PREFIX (#844) * fix(travis): disable libghdl on mac * feat(python/libghdl): add support for GHDL_BIN_PATH and VUNIT_GHDL_PATH
8800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#include "BigIntegerAlgorithms.hh"

BigUnsigned gcd(BigUnsigned a, BigUnsigned b) {
	BigUnsigned trash;
	// Neat in-place alternating technique.
	for (;;) {
		if (b.isZero())
			return a;
		a.divideWithRemainder(b, trash);
		if (a.isZero())
			return b;
		b.divideWithRemainder(a, trash);
	}
}

void extendedEuclidean(BigInteger m, BigInteger n,
		BigInteger &g, BigInteger &r, BigInteger &s) {
	if (&g == &r || &g == &s || &r == &s)
		throw "BigInteger extendedEuclidean: Outputs are aliased";
	BigInteger r1(1), s1(0), r2(0), s2(1), q;
	/* Invariants:
	 * r1*m(orig) + s1*n(orig) == m(current)
	 * r2*m(orig) + s2*n(orig) == n(current) */
	for (;;) {
		if (n.isZero()) {
			r = r1; s = s1; g = m;
			return;
		}
		// Subtract q times the second invariant from the first invariant.
		m.divideWithRemainder(n, q);
		r1 -= q*r2; s1 -= q*s2;

		if (m.isZero()) {
			r = r2; s = s2; g = n;
			return;
		}
		// Subtract q times the first invariant from the second invariant.
		n.divideWithRemainder(m, q);
		r2 -= q*r1; s2 -= q*s1;
	}
}

BigUnsigned modinv(const BigInteger &x, const BigUnsigned &n) {
	BigInteger g, r, s;
	extendedEuclidean(x, n, g, r, s);
	if (g == 1)
		// r*x + s*n == 1, so r*x === 1 (mod n), so r is the answer.
		return (r % n).getMagnitude(); // (r % n) will be nonnegative
	else
		throw "BigInteger modinv: x and n have a common factor";
}

BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent,
		const BigUnsigned &modulus) {
	BigUnsigned ans = 1, base2 = (base % modulus).getMagnitude();
	BigUnsigned::Index i = exponent.bitLength();
	// For each bit of the exponent, most to least significant...
	while (i > 0) {
		i--;
		// Square.
		ans *= ans;
		ans %= modulus;
		// And multiply if the bit is a 1.
		if (exponent.getBit(i)) {
			ans *= base2;
			ans %= modulus;
		}
	}
	return ans;
}