389

I'm thinking in particular of how to display pagination controls, when using a language such as C# or Java.

If I have x items which I want to display in chunks of y per page, how many pages will be needed?

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
Ian Nelson
  • 57,123
  • 20
  • 76
  • 103
  • 1
    Am I missing something? y/x + 1 works great (provided you know the / operator always rounds down). – rikkit Aug 07 '12 at 16:03
  • 66
    @rikkit - if y and x are equal, y/x + 1 is one too high. – Ian Nelson Aug 07 '12 at 19:15
  • 1
    For anyone just now finding this, [this answer to a dupe question](http://stackoverflow.com/a/4846569/4163002) avoids unnecessary conversion to double *and* avoids overflow concerns in addition to providing a clear explanation. – ZX9 Dec 21 '16 at 14:54
  • 3
    @IanNelson more generally if `x` is divisible by `y`, `y/x + 1` would be one too high. – Ohad Schneider Aug 24 '17 at 13:10
  • 1
    @ZX9 No, it does not avoid overflow concerns. It's exactly the same solution as Ian Nelson posted here. – user247702 Dec 01 '17 at 14:22

19 Answers19

571

Found an elegant solution:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

Source: Number Conversion, Roland Backhouse, 2001

Ian Nelson
  • 57,123
  • 20
  • 76
  • 103
  • 15
    -1 because of the overflow bug pointed out by [Brandon DuRette](http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division/96921#96921) – finnw May 04 '11 at 09:21
  • 36
    Mr Obvious says: Remember to make sure that recordsPerPage is not zero – Adam Gent May 19 '11 at 11:41
  • 7
    Good job, I can't believe C# doesn't have integer ceiling. – gosukiwi Aug 29 '12 at 18:32
  • 3
    Yup, here I am in mid-2017 stumbling across this great answer after trying several much more complex approaches. – Mifo Jul 29 '17 at 23:41
  • 3
    For languages with a proper Euclidian-division operator such as Python, an even simpler approach would be `pageCount = -((-records) // recordsPerPage)`. – supercat Jul 04 '18 at 16:45
  • +1 because this also works with unsigned numbers (relevant in other languages): The "simplification" `(records - 1) / recordsPerPage + 1` underflows when records == 0. – user2394284 Mar 18 '19 at 13:49
  • It does have Ceiling. It's under Math, not Integer. – John Lord Mar 04 '22 at 22:44
  • Thanks, the solution is elegant without external libraries. @finnw to avoid the overflow bug, just split in two divisions `int pageCount = records / recordsPerPage + (recordsPerPage - 1) / recordsPerPage;` – Raymond Chenon Feb 22 '23 at 11:05
244

Converting to floating point and back seems like a huge waste of time at the CPU level.

Ian Nelson's solution:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

Can be simplified to:

int pageCount = (records - 1) / recordsPerPage + 1;

AFAICS, this doesn't have the overflow bug that Brandon DuRette pointed out, and because it only uses it once, you don't need to store the recordsPerPage specially if it comes from an expensive function to fetch the value from a config file or something.

I.e. this might be inefficient, if config.fetch_value used a database lookup or something:

int pageCount = (records + config.fetch_value('records per page') - 1) / config.fetch_value('records per page');

This creates a variable you don't really need, which probably has (minor) memory implications and is just too much typing:

int recordsPerPage = config.fetch_value('records per page')
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;

This is all one line, and only fetches the data once:

int pageCount = (records - 1) / config.fetch_value('records per page') + 1;
rjmunro
  • 27,203
  • 20
  • 110
  • 132
  • 6
    +1, the issue of zero records still returning 1 pageCount is actually handy, since I would still want 1 page, showing the placeholder/fake row of "no records match your criteria", helps avoid any "0 page count" issues in whatever pagination control you use. – Timothy Walters Mar 17 '11 at 02:38
  • 33
    Be aware that the two solutions do not return the same pageCount for zero records. This simplified version will return 1 pageCount for zero records, whereas the Roland Backhouse version returns 0 pageCount. Fine if that's what you desire, but the two equations are not equivalent when performed by C#/Java stylee integer division. – Ian Nelson Sep 06 '11 at 07:48
  • 13
    tiny edit for clarity for people scanning it and missing bodmas when changing to the simpification from the Nelson solution (like I did the first time !), the simplification with brackets is... int pageCount = ((records - 1) / recordsPerPage) + 1; – dave heywood May 02 '14 at 08:41
  • 1
    You should add parenthesis to the simplified version so that it doesn't rely on a specific order of operations. i.e., ((records - 1) / recordsPerPage) + 1. – Martin Feb 05 '16 at 17:57
  • Also, it's simpler to translate it to other division problems; Good to know there's a simple way to do ceiling division with integers. – BrainSlugs83 Jul 08 '16 at 21:25
  • 4
    @Ian, this answer doesn't ALWAYS return 1. It can return 0 if your recordsPerPage is "1" and there are 0 records: `-1 / 1 + 1 = 0`. While that's not a super common occurrence, it's important to keep in mind if you're allowing users to adjust page size. So either don't allow users to have a page size of 1, do a check on page size, or both (probably preferable to avoid unexpected behavior). – Michael Jan 09 '18 at 23:39
  • This is no solution for the overflow, though. With Ian's solution you get twice the usable range if you use unsigned integers, and `records + recordsPerPage` has an upper bound of 2^32 or 2^64. With this solution you can only use a signed integer for `records`, otherwise it will overflow at `0 - 1`, so `records` is upper bound by 2^31 or 2^63. – JimmyMcHoover Apr 27 '18 at 12:17
  • 1
    FWIW, I was doing something similar, calculating the max page number, and if the page numbers are 0-based, it becomes a nice, clean... maxPage = (records - 1) / recordsPerPage. Only thing is it has the same issue when records==0... if recordsPerPage is 1, the result is -1 (what I'd want) but if recordsPerPage>1, you get 0. – KevinVictor Mar 05 '20 at 20:53
99

For C# the solution is to cast the values to a double (as Math.Ceiling takes a double):

int nPages = (int)Math.Ceiling((double)nItems / (double)nItemsPerPage);

In java you should do the same with Math.ceil().

trampster
  • 8,598
  • 4
  • 37
  • 52
Huppie
  • 11,263
  • 4
  • 32
  • 34
84

This should give you what you want. You will definitely want x items divided by y items per page, the problem is when uneven numbers come up, so if there is a partial page we also want to add one page.

int x = number_of_items;
int y = items_per_page;

// with out library
int pages = x/y + (x % y > 0 ? 1 : 0)

// with library
int pages = (int)Math.Ceiling((double)x / (double)y);
Nick Berardi
  • 54,393
  • 15
  • 113
  • 135
  • 8
    x/y + !!(x % y) avoids the branch for C-like languages. Odds are good, however, your compiler is doing that anyway. – Rhys Ulerich Jan 26 '10 at 15:57
  • 2
    +1 for not overflowing like the answers above... though converting ints to doubles just for Math.ceiling and then back again is a bad idea in performance sensitive code. – Cogwheel Feb 25 '15 at 01:54
  • 4
    @RhysUlerich that doesn't work in c# (can't directly convert an int to a bool). rjmunro's solution is the only way to avoid branching I think. – smead Apr 09 '16 at 01:05
19

The integer math solution that Ian provided is nice, but suffers from an integer overflow bug. Assuming the variables are all int, the solution could be rewritten to use long math and avoid the bug:

int pageCount = (-1L + records + recordsPerPage) / recordsPerPage;

If records is a long, the bug remains. The modulus solution does not have the bug.

Ajay2707
  • 5,690
  • 6
  • 40
  • 58
Brandon DuRette
  • 4,810
  • 5
  • 25
  • 31
  • 6
    I don't think you are realistically going to hit this bug in the scenario presented. 2^31 records is quite a lot to be having to page through. – rjmunro Feb 05 '09 at 00:18
  • 8
    @rjmunro, [real-world example here](http://code.google.com/p/guava-libraries/issues/detail?id=616) – finnw May 04 '11 at 09:20
  • 1
    @finnw: AFAICS, there isn't a real-world example on that page, just a report of someone else finding the bug in a theoretical scenario. – rjmunro Nov 29 '11 at 11:44
  • @rjmunro, I was referring to this: *"I came across this oddity while I was working on an SWT-based table viewer that supports pagination. Internally, the table viewer uses Lists.partition() to split its input elements into pages of a fixed size."* – finnw Nov 29 '11 at 15:11
  • 6
    Yes, I was being pedantic in pointing out the bug. Many bugs can exist in perpetuity without ever causing any problems. A bug of the same form existed in the JDK's implementation of binarySearch for some nine years, before someone reported it (http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html). I guess the question is, regardless of how unlikely you are to encounter this bug, why not fix it up front? – Brandon DuRette Nov 29 '11 at 17:59
  • 4
    Also, it should be noted that it's not just the number of elements that are paged that matter, it's also the page size. So, if you're building a library and someone chooses to not page by passing 2^31-1 (Integer.MAX_VALUE) as the page size, then the bug is triggered. – Brandon DuRette Nov 29 '11 at 18:03
10

HOW TO ROUND UP THE RESULT OF INTEGER DIVISION IN C#

I was interested to know what the best way is to do this in C# since I need to do this in a loop up to nearly 100k times. Solutions posted by others using Math are ranked high in the answers, but in testing I found them slow. Jarod Elliott proposed a better tactic in checking if mod produces anything.

int result = (int1 / int2);
if (int1 % int2 != 0) { result++; }

I ran this in a loop 1 million times and it took 8ms. Here is the code using Math:

int result = (int)Math.Ceiling((double)int1 / (double)int2);

Which ran at 14ms in my testing, considerably longer.

SendETHToThisAddress
  • 2,756
  • 7
  • 29
  • 54
  • Yeah, floating point division is pretty "terrible". :) This truth goes way back since the dawn of the first floating point CPU's/FPU's, really. In fact, many game developers and others demanding high performance go through hoops to be able to use integer math. – Jonas Jun 15 '23 at 18:04
  • I'm going to make an assumption that it takes longer because they're bigger data types, more digits to manage. – SendETHToThisAddress Jun 16 '23 at 23:58
9

In need of an extension method:

    public static int DivideUp(this int dividend, int divisor)
    {
        return (dividend + (divisor - 1)) / divisor;
    }

No checks here (overflow, DivideByZero, etc), feel free to add if you like. By the way, for those worried about method invocation overhead, simple functions like this might be inlined by the compiler anyways, so I don't think that's where to be concerned. Cheers.

P.S. you might find it useful to be aware of this as well (it gets the remainder):

    int remainder; 
    int result = Math.DivRem(dividend, divisor, out remainder);
Nicholas Petersen
  • 9,104
  • 7
  • 59
  • 69
  • 1
    This is incorrect. For example: `DivideUp(4, -2)` returns 0 (should be -2). **It is only correct for non-negative integers** which is not clear from the answer or from the function's interface. – Thash Apr 25 '17 at 21:31
  • 7
    Thash, why don't you do something useful like add the little extra check then if the number is negative, instead of voting my answer down, and incorrectly making the blanket statement: "This is incorrect," when in fact it's just an edge case. I already made it clear you should do other checks first: "No checks here (overflow, DivideByZero, etc), **feel free to add if you like**." – Nicholas Petersen Apr 25 '17 at 23:18
  • 2
    The question mentioned "I'm thinking in particular of how to display **pagination controls**" so negative numbers would have been out of bounds anyways. Again, just do something useful and suggest an added check if you want, it's a team effort man. – Nicholas Petersen Apr 25 '17 at 23:22
  • 1
    I didn't mean to be rude and I'm sorry if you take it that way. The question was "How to round up the result of integer division". The author mentioned pagination but other people may have different needs. I think it would be better if your function somehow reflected that it does not work for negative integers since it is not clear from the interface (for example a differen name or argument types). To work with negative integers,you can for example take an absolute value of the dividend and divisor and multiply the result by its sign. – Thash Apr 26 '17 at 07:51
8

A variant of Nick Berardi's answer that avoids a branch:

int q = records / recordsPerPage, r = records % recordsPerPage;
int pageCount = q - (-r >> (Integer.SIZE - 1));

Note: (-r >> (Integer.SIZE - 1)) consists of the sign bit of r, repeated 32 times (thanks to sign extension of the >> operator.) This evaluates to 0 if r is zero or negative, -1 if r is positive. So subtracting it from q has the effect of adding 1 if records % recordsPerPage > 0.

Community
  • 1
  • 1
finnw
  • 47,861
  • 24
  • 143
  • 221
4

Another alternative is to use the mod() function (or '%'). If there is a non-zero remainder then increment the integer result of the division.

Jarod Elliott
  • 15,460
  • 3
  • 35
  • 34
4

For records == 0, rjmunro's solution gives 1. The correct solution is 0. That said, if you know that records > 0 (and I'm sure we've all assumed recordsPerPage > 0), then rjmunro solution gives correct results and does not have any of the overflow issues.

int pageCount = 0;
if (records > 0)
{
    pageCount = (((records - 1) / recordsPerPage) + 1);
}
// no else required

All the integer math solutions are going to be more efficient than any of the floating point solutions.

Mike
  • 1,227
  • 10
  • 15
  • This method is unlikely to be a performance bottleneck. And if it is, you should also consider the cost of the branch. – finnw May 04 '11 at 13:14
2

I do the following, handles any overflows:

var totalPages = totalResults.IsDivisble(recordsperpage) ? totalResults/(recordsperpage) : totalResults/(recordsperpage) + 1;

And use this extension for if there's 0 results:

public static bool IsDivisble(this int x, int n)
{
           return (x%n) == 0;
}

Also, for the current page number (wasn't asked but could be useful):

var currentPage = (int) Math.Ceiling(recordsperpage/(double) recordsperpage) + 1;
Sam Jones
  • 4,443
  • 2
  • 40
  • 45
2

you can use

(int)Math.Ceiling(((decimal)model.RecordCount )/ ((decimal)4));
H.M.Mubashir
  • 170
  • 1
  • 14
0

Alternative to remove branching in testing for zero:

int pageCount = (records + recordsPerPage - 1) / recordsPerPage * (records != 0);

Not sure if this will work in C#, should do in C/C++.

flux
  • 189
  • 3
  • 13
0

I made this for me, thanks to Jarod Elliott & SendETHToThisAddress replies.

public static int RoundedUpDivisionBy(this int @this, int divider)
{        
    var result = @this / divider;
    if (@this % divider is 0) return result;
    return result + Math.Sign(@this * divider);
}

Then I realized it is overkill for the CPU compared to the top answer. However, I think it's readable and works with negative numbers as well.

Jin-K
  • 105
  • 1
  • 7
0

Since Java 18, Math.ceilDiv is available for this purpose, see https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/Math.html#ceilDiv(int,int)

DaHoC
  • 314
  • 1
  • 4
  • 14
-1

A generic method, whose result you can iterate over may be of interest:

public static Object[][] chunk(Object[] src, int chunkSize) {

    int overflow = src.length%chunkSize;
    int numChunks = (src.length/chunkSize) + (overflow>0?1:0);
    Object[][] dest = new Object[numChunks][];      
    for (int i=0; i<numChunks; i++) {
        dest[i] = new Object[ (i<numChunks-1 || overflow==0) ? chunkSize : overflow ];
        System.arraycopy(src, i*chunkSize, dest[i], 0, dest[i].length); 
    }
    return dest;
}
  • [Guava](http://code.google.com/p/guava-libraries/) has a similar method ([`Lists.partition(List, int)`](http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/collect/Lists.html#partition%28java.util.List,%20int%29)) and ironically the `size()` method of the resulting `List` (as of `r09`) suffers from the overflow bug mentioned in [Brandon DuRette's answer](http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division/96921#96921). – finnw May 04 '11 at 13:21
-2

The following should do rounding better than the above solutions, but at the expense of performance (due to floating point calculation of 0.5*rctDenominator):

uint64_t integerDivide( const uint64_t& rctNumerator, const uint64_t& rctDenominator )
{
  // Ensure .5 upwards is rounded up (otherwise integer division just truncates - ie gives no remainder)
  return (rctDenominator == 0) ? 0 : (rctNumerator + (int)(0.5*rctDenominator)) / rctDenominator;
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211
-3

I had a similar need where I needed to convert Minutes to hours & minutes. What I used was:

int hrs = 0; int mins = 0;

float tm = totalmins;

if ( tm > 60 ) ( hrs = (int) (tm / 60);

mins = (int) (tm - (hrs * 60));

System.out.println("Total time in Hours & Minutes = " + hrs + ":" + mins);
Juan Mellado
  • 14,973
  • 5
  • 47
  • 54
-5

You'll want to do floating point division, and then use the ceiling function, to round up the value to the next integer.

Kibbee
  • 65,369
  • 27
  • 142
  • 182