473,394 Members | 1,778 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Arbitrary precision integer arithmetic: ceiling?

I need to apply the ceiling function to arbitrary sized (long) integers.
However, division automatically returns the type of its operands, so that,
for example: math.ceil(7/4) returns 1. I can use float, as in:
math.ceil(7/float(4)), except that for very large integers float causes an
unacceptable loss of precision.

What is the best way of finding a ceiling of a quotient of arbitrary sized
integers?

Thanks,
Alasdair
Mar 8 '08 #1
15 3868
Alasdair <am****@gmail.comwrites:
What is the best way of finding a ceiling of a quotient of arbitrary sized
integers?
ceiling(a/b) = (a+b-1)//b
Mar 8 '08 #2
Alasdair wrote:
I need to apply the ceiling function to arbitrary sized (long) integers.
However, division automatically returns the type of its operands, so that,
for example: math.ceil(7/4) returns 1. I can use float, as in:
math.ceil(7/float(4)), except that for very large integers float causes an
unacceptable loss of precision.

What is the best way of finding a ceiling of a quotient of arbitrary sized
integers?
Use divmod() to get the quotient and the remainder at the same time. Add 1 to
the quotient if and only the remainder is greater than 0.
In [11]: def qceil(x, y):
....: """ Find the ceiling of a quotient x/y.
....:
....: This is especially useful for very large Python long integers.
....: """
....: q, r = divmod(x, y)
....: if r 0:
....: q += 1
....: return q
....:

In [13]: qceil(7, 4)
Out[13]: 2

In [14]: qceil(8, 4)
Out[14]: 2

In [15]: qceil(9, 4)
Out[15]: 3

In [16]: qceil(100000000000000000000000003, 10)
Out[16]: 10000000000000000000000001L

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Mar 8 '08 #3
On Mar 8, 6:26*pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
Alasdair <amc...@gmail.comwrites:
What is the best way of finding a ceiling of a quotient of arbitrary sized
integers?

ceiling(a/b) = (a+b-1)//b
I prefer:

ceiling(a/b) = -(-a)//b

which also works if a and b are something other
than integers (e.g. rational numbers).

Mark
Mar 9 '08 #4
On Sat, 08 Mar 2008 17:09:11 -0800, Mark Dickinson wrote:
On Mar 8, 6:26Â*pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
>Alasdair <amc...@gmail.comwrites:
What is the best way of finding a ceiling of a quotient of arbitrary
sized integers?

ceiling(a/b) = (a+b-1)//b

I prefer:

ceiling(a/b) = -(-a)//b

which also works if a and b are something other than integers (e.g.
rational numbers).

Unfortunately it doesn't give the right answer.
>>a, b = 101.0, 10.0
-(-a)//b # should be 11.0
10.0
>>a, b = -101.0, 10.0
-(-a)//b # should be -10.0
-11.0

Looks like you've confused ceiling() and floor().

(And the ease that these mistakes can happen is why such fundamental
functions should be in the standard library, no matter how easy they are
to implement.)
--
Steven
Mar 9 '08 #5
On Mar 8, 8:48*pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:
On Sat, 08 Mar 2008 17:09:11 -0800, Mark Dickinson wrote:
I prefer:
ceiling(a/b) = -(-a)//b

Unfortunately it doesn't give the right answer.
>a, b = 101.0, 10.0
-(-a)//b *# should be 11.0
10.0
>a, b = -101.0, 10.0
-(-a)//b *# should be -10.0

-11.0

Looks like you've confused ceiling() and floor().
Whoops, you're right. No, I didn't confuse ceiling and floor;
I misplaced the parentheses. I meant to type:

ceiling(a/b) = -(-a//b)

Mark
Mar 9 '08 #6
On Sat, 08 Mar 2008 15:26:35 -0800, Paul Rubin wrote:
Alasdair <am****@gmail.comwrites:
>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
Mar 9 '08 #7

"Steven D'Aprano" <st***@REMOVE-THIS-cybersource.com.auwrote in message
news:13*************@corp.supernews.com...
| On Sat, 08 Mar 2008 17:09:11 -0800, Mark Dickinson wrote:
|
| On Mar 8, 6:26 pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
| >Alasdair <amc...@gmail.comwrites:
| What is the best way of finding a ceiling of a quotient of arbitrary
| sized integers?
| >>
| >ceiling(a/b) = (a+b-1)//b
| >
| I prefer:
| >
| ceiling(a/b) = -(-a)//b

Obvious typo: -(-a)//b == a//b

This should be -(-a//b) == -((-a)//b)

| Unfortunately it doesn't give the right answer.
| Looks like you've confused ceiling() and floor().
|
| (And the ease that these mistakes can happen is why such fundamental
| functions should be in the standard library, no matter how easy they are
| to implement.)

I'll let Paul say whether is was a typo, due to answering too quickly, or a
logic error, but I suspect the former. *Any* expression can be mistyped.

tjr

Mar 9 '08 #8
On Mar 8, 9:19*pm, "Terry Reedy" <tjre...@udel.eduwrote:
Obvious typo: -(-a)//b == a//b

This should be -(-a//b) == -((-a)//b)
Yes: thanks for the correction!

A lesson to me to include parentheses even when redundant...

This reminds me of the following parenthesization gem
(see next to last line):

def isqrt(n):
"""Find the closest integer to sqrt(n), for n a positive
integer."""
a, b = n, 1
while a != b:
a, b = a -- n // a >1, a
return a

Mark
Mar 9 '08 #9
On Sun, 09 Mar 2008 01:48:21 +0000, Steven D'Aprano wrote:
(And the ease that these mistakes can happen is why such fundamental
functions should be in the standard library, no matter how easy they are
to implement.)
Which, of course, they are.

math.ceil() and math.floor()

I knew that. *cough*

--
Steven
Mar 9 '08 #10
On Sun, 09 Mar 2008 10:11:53 +1100, Alasdair wrote:
I need to apply the ceiling function to arbitrary sized (long) integers.
However, division automatically returns the type of its operands, so
that, for example: math.ceil(7/4) returns 1. I can use float, as in:
math.ceil(7/float(4)), except that for very large integers float causes
an unacceptable loss of precision.

What is the best way of finding a ceiling of a quotient of arbitrary
sized integers?
def quot_ceil(a, b):
"""Returns the integer ceiling of the quotient of longints."""
q, r = divmod(a, b)
if r: return q+1
else: return q

--
Steven
Mar 9 '08 #11
On Sun, 09 Mar 2008 02:16:39 +0000, Steven D'Aprano wrote:
On Sat, 08 Mar 2008 15:26:35 -0800, Paul Rubin wrote:
>Alasdair <am****@gmail.comwrites:
>>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.
But of course you didn't intend it to work with floats, did you?

Sigh.

I'm just glad I didn't rant about people who think that floats are just
like reals when they're not.
--
Steven
Mar 9 '08 #12
Steven D'Aprano <st***@REMOVE-THIS-cybersource.com.auwrites:
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 should have mentioned (a+b-1)//b expects a and b to be positive
integers.
Mar 9 '08 #13
On Sat, 08 Mar 2008 21:32:04 -0800, Paul Rubin wrote:
I should have mentioned (a+b-1)//b expects a and b to be positive
integers.
Oh, I don't think that would have made any difference. I think I'm seeing
floats everywhere today, including coming out of the walls.
--
Steven
Mar 9 '08 #14
Thanks, all - you've been most helpful. By the way, what does // do? I
haven't yet run down its definition in the manual.

-A.
Mar 9 '08 #15
On Sun, 09 Mar 2008 20:57:15 +1100, Alasdair wrote:
Thanks, all - you've been most helpful. By the way, what does // do? I
haven't yet run down its definition in the manual.
// is integer division.
>>10//5
2
>>11//5
2

In Python 2.5 and older, / means integer division, unless you do

from __future__ import division

in which case / is true division, that is:
>>10/5
2
>>11/5
2.5
In Python 3.x, / will always be true division, and you won't need the
import.
--
Steven
Mar 9 '08 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Thinkit | last post by:
Are there any packages for arbitrary precision binary floats? Something along the lines of Gnu Multi Precision. I saw quite a few rationals classes, but not this. Just looking to be able to use...
4
by: Roger Leigh | last post by:
Hello, I'm writing a fixed-precision floating point class, based on the ideas in the example fixed_pt class in the "Practical C++ Programming" book by Steve Oualline (O' Reilly). This uses a...
2
by: cpptutor2000 | last post by:
Could some C++ guru please help me? I am using a BigInteger class which is really a wrapper around a C source file(mpi.c) that does arbitrary precision arithmetic operations. When I compile the C...
37
by: Protoman | last post by:
Hi!!! Protoman here, I need to write an infinite precision number class b/c I want to compute pi. Give me some sample code. Also, when I run my program and it computes pi, will my computer freeze...
3
by: Madan | last post by:
Hi all, I had problem regarding float/double arithmetic only with + and - operations, which gives inaccurate precisions. I would like to know how the arithmetic operations are internally handled...
0
by: Jeremy Watts | last post by:
Hi, Does VB.net have an 'arbitrary length' arithmetic feature? Meaning can it handle very large real/integer number arithmetic symbolically like some other languages can? PHP for instance...
2
by: rupert | last post by:
i've got the following code: #include <iostream> #include <string> #include <vector> #include <iomanip> using namespace std; int main(double argc, char* argv) { double r = 0.01;
11
by: ChrisM | last post by:
Hi Guys, I'm looking for a function that will return the lowest integer that is greater than or equal to a decimal number. eg. 3.1(decimal) returns 4(integer) 3.9(decimal) returns...
2
by: Rob Clewley | last post by:
Dear Pythonistas, How many times have we seen posts recently along the lines of "why is it that 0.1 appears as 0.10000000000000001 in python?" that lead to posters being sent to the definition...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.