Arbitrary precision integer arithmetic: ceiling?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Mar 9 03:16:39 CET 2008


On Sat, 08 Mar 2008 15:26:35 -0800, Paul Rubin wrote:

> Alasdair <amca01 at gmail.com> writes:
>> What is the best way of finding a ceiling of a quotient of arbitrary
>> sized integers?
> 
> ceiling(a/b) = (a+b-1)//b


Unfortunately that doesn't work reliably.

>>> a, b = 9007199254741000.0, -3.0
>>> a/b
-3002399751580333.5
>>> (a+b-1)//b  # should be -3002399751580333
-3002399751580332.0



I make no claim that this is the most efficient way to do it, but this 
should work:


def splitfloat(f):
    """Return the integer and fraction part of a float."""
    fp = abs(f) % 1.0
    ip = abs(f) - fp
    if f < 0:
        ip, fp = -ip, -fp
    return (ip, fp)

def ceil(f):
    ip, fp = splitfloat(f)
    if fp == 0:
        return ip
    elif f < 0:
        return ip
    else:
        return ip + 1


>>> a, b = 9007199254741000.0, -3.0
>>> ceil(a/b)
-3002399751580333.0
>>> a, b = 9007199254741000.0, 3.0
>>> ceil(a/b)
3002399751580334.0

It even works for infinities, if supported by your platform:

>>> ceil(1.0/inf)
0.0

(Disclaimer: if you consider that 1.0/inf is a tiny bit more than zero, 
and therefore you want ceil(1.0/inf) to give 1.0, then you will disagree 
with me.)



-- 
Steven



More information about the Python-list mailing list