[Python-ideas] Add the imath module
Steven D'Aprano
steve at pearwood.info
Thu Jul 12 12:05:29 EDT 2018
On Thu, Jul 12, 2018 at 02:55:58PM +0300, Serhiy Storchaka wrote:
> What are your thoughts about adding a new imath module for integer
> mathematics?
I'm not sure that we need a specific module for integer-valued maths. I
think a more important change would be to allow math functions to be
written in Python, not just C:
- move the current math library to a private _math library;
- add math.py, which calls "from _math import *".
I often miss having a good, fast, integer square root function in the
stdlib. I have a slow implementation here:
http://code.activestate.com/recipes/577821-integer-square-root-function/
and as the commentary discusses, a lot of implementations on the
internet are buggy.
As well as isqrt(n), there's also nsqrt(n), to return the integer
nearest to the square root of n. They're equivalent to:
isqrt = floor sqrt
nsqrt = round sqrt
without overflowing for large n. (Presumably there's a ceiling sqrt
function too, but I've never needed it, or seen anyone else use it.)
As far as your other suggestions:
* factorial(n)
* gcd(n, m)
Moving those seem like a fairly pedantic change. But if we did it, we
could allow gcd to take an arbitrary number of values:
gcd(*args)
and add a least common multiple function to match.
* as_integer_ration(x)
I think that's mispelled "ratio" :-)
There's currently a private function statistics._exact_ratio which
does that.
* binom(n, k)
If we have number of combinations, I'd like to have number of
permutations as well.
* isprime(n)
* primes()
Primality testing and generation of primes is a bigger job than it might
seem, probably deserving of an entire library. (Not necessarily in the
std lib.)
But if we did provide a "batteries included" solution, it should also
include next prime and previous prime functions.
For isprime(), I have a pure-Python solution which is not too shabby,
capable of giving exact results for all integers up to 2**64 and
probabilitistic results above that. Despite being pure Python, it's
reasonably fast. In the REPL, these are essentially instantaneous to the
naked eye:
py> pyprimes.prev_prime(2**64)
18446744073709551557L
py> pyprimes.is_prime(18446744073709551557L)
True
py> pyprimes.next_prime(2**64)
pyprimes/__init__.py:278: MaybeComposite: 18446744073709551629 is only
only probably prime
warnings.warn(message, MaybeComposite)
18446744073709551629L
At the moment this is Python 2 only and frankly overkill for the stdlib.
I have something like a dozen different implementations for generating
or testing primes, some of which are (intentionally) just awful. One of
my favourite so-awful-it's-good algorithms is this one for testing
whether a number is prime:
def isprime(n):
# Kids: don't try this at home!
return not re.match(r'^1?$|^(11+?)\1+$', '1'*n)
But if there is interest in a pure-Python solution, I might be able to
find time to clean it up to stdlib quality. (Not the regex solution,
obviously.)
--
Steve
More information about the Python-ideas
mailing list