如何整数除法的结果?

我特别想到如何使用C#或Java等语言来显示分页控件。

如果我有x个项目,我想每个页面以y块显示,那么需要多less页面?

find了优雅的解决scheme

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

来源: 数字转换,Roland Backhouse,2001

转换到浮点和后面看起来像在CPU级别的时间的巨大浪费。

伊恩·尼尔森的解决scheme:

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

可以简化为:

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

AFAICS,它没有Brandon DuRette指出的溢出漏洞,而且由于它只使用了一次,所以如果它来自一个昂贵的函数来从configuration文件中获取值,则不需要专门存储recordsPerPage,一些东西。

即这可能是低效的,如果config.fetch_value使用数据库查找或某事:

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

这会创build一个你并不真正需要的variables,这个variables可能具有(较小的)内存含义,而且input太多:

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

这全是一行,只有一次提取数据:

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

这应该给你你想要的。 你一定会希望x项目每页y项目分开,问题是当不均匀的数字出现,所以如果有一个局部页面,我们也想添加一个页面。

 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); 

对于C#解决scheme是将值转换为double(如Math.Ceiling需要双):

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

在Java中,你应该使用Math.ceil()。

伊恩提供的整数math解决scheme是不错的,但遭受整数溢出错误。 假设variables都是int ,解决scheme可以重写为使用longmath并避免错误:

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

如果recordslong ,错误依然存在。 模数解决scheme没有这个bug。

尼克·贝拉尔迪 ( Nick Berardi)回答的一个变种,避免了一个分支:

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

注意: (-r >> (Integer.SIZE - 1))r的符号位组成,重复32次(感谢>>操作符的符号扩展)。如果r为零或负,则计算结果为0。 1如果r是正数。 因此,如果records % recordsPerPage > 0 ,则从q减去它具有加1的效果。

对于logging== 0,rjmunro的解决scheme给出了1.正确的解决scheme是0.也就是说,如果你知道logging> 0(我确定我们都假设recordsPerPage> 0),那么rjmunro解决scheme给出了正确的结果,没有任何溢出问题。

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

所有的整数math解决scheme将比任何浮点解决scheme更有效率。

另一种select是使用mod()函数(或'%')。 如果有一个非零余数,则增加除法的整数结果。

需要扩展的方法:

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

在这里没有检查(溢出, DivideByZero等),随意添加,如果你喜欢。 顺便说一下,对于那些担心方法调用开销的人来说,这样的简单函数可能会被编译器内联,所以我不认为这是关注的地方。 干杯。

PS,你可能会发现这也是有用的(它得到的余数):

  int remainder; int result = Math.DivRem(dividend, divisor, out remainder); 

替代删除分支testing为零:

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

不知道这是否会在C#中工作,应该在C / C ++中。

我做了以下处理任何溢出:

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

如果有0个结果,则使用此扩展名:

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

此外,对于当前页码(没有问,但可能是有用的):

 var currentPage = (int) Math.Ceiling(recordsperpage/(double) recordsperpage) + 1; 

一个generics的方法,其结果可以迭代可能是有趣的:

 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; } 

我有类似的需求,我需要将分钟转换为小时和分钟。 我用的是:

 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); 

下面应该比上面的解决scheme做得更好,但是以性能为代价(由于0.5 * rctD分母的浮点计算):

 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; } 

你会想要做浮点除法,然后使用ceiling函数,把值整理到下一个整数。