在使用C#或Java等语言时,我正在考虑如何显示分页控件。
如果我有 x 项目,我想在每页的 y 块中显示,那么需要多少页?
答案 0 :(得分:434)
找到一个优雅的解决方案:
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;
答案 1 :(得分:178)
转换为浮点和返回似乎在CPU级别上浪费了大量时间。
Ian Nelson的解决方案:
int pageCount = (records + recordsPerPage - 1) / recordsPerPage;
可以简化为:
int pageCount = (records - 1) / recordsPerPage + 1;
AFAICS,这没有Brandon DuRette指出的溢出错误,并且因为它只使用它一次,如果它来自一个昂贵的函数来获取来自a的值,你不需要特别存储recordsPerPage配置文件或其他东西。
即。如果config.fetch_value使用数据库查找或其他东西,这可能效率低下:
int pageCount = (records + config.fetch_value('records per page') - 1) / config.fetch_value('records per page');
这会创建一个你并不真正需要的变量,它可能具有(次要的)内存含义并且输入太多:
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;
答案 2 :(得分:66)
对于C#,解决方案是将值转换为double(因为Math.Ceiling需要加倍):
int nPages = (int)Math.Ceiling((double)nItems / (double)nItemsPerPage);
在java中,您应该对Math.ceil()执行相同的操作。
答案 3 :(得分:64)
这应该可以满足您的需求。您肯定希望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);
答案 4 :(得分:18)
Ian提供的整数数学解决方案很好,但是遇到整数溢出错误。假设变量都是int
,可以重写解决方案以使用long
数学并避免错误:
int pageCount = (-1L + records + recordsPerPage) / recordsPerPage;
如果records
是long
,则错误仍然存在。模数解决方案没有错误。
答案 5 :(得分:7)
避免分支的Nick Berardi's answer变体:
int q = records / recordsPerPage, r = records % recordsPerPage;
int pageCount = q - (-r >> (Integer.SIZE - 1));
注意:(-r >> (Integer.SIZE - 1))
由r
的符号位组成,重复32次(感谢>>
运算符的符号扩展。)如果r
,则计算结果为0为零或负,如果r
为正,则为-1。因此,从q
中减去它会产生records % recordsPerPage > 0
时添加1的效果。
答案 6 :(得分:4)
对于记录== 0,rjmunro的解决方案给出1.正确的解决方案是0.这就是说,如果你知道记录> 0(我确定我们都假设记录PerPage> 0),然后rjmunro解决方案给出了正确的结果,并且没有任何溢出问题。
int pageCount = 0;
if (records > 0)
{
pageCount = (((records - 1) / recordsPerPage) + 1);
}
// no else required
所有整数数学解决方案将比任何浮点解决方案更有效。
答案 7 :(得分:3)
需要扩展方法:
public static int DivideUp(this int dividend, int divisor)
{
return (dividend + (divisor - 1)) / divisor;
}
此处没有检查(溢出,DivideByZero
等),如果您愿意,可随意添加。顺便说一句,对于担心方法调用开销的人来说,编译器可能会简单地编写这样的简单函数,所以我不认为这是关注的地方。欢呼声。
P.S。你可能会发现它也很有用(它得到余数):
int remainder;
int result = Math.DivRem(dividend, divisor, out remainder);
答案 8 :(得分:2)
另一种方法是使用mod()函数(或'%')。如果存在非零余数,则递增除法的整数结果。
答案 9 :(得分:1)
如何计算C#中整数除法的结果
我很想知道在C#中最好的方法是什么,因为我需要循环进行近十万次。其他人使用 Math 发布的解决方案在答案中排名很高,但是在测试中我发现它们很慢。 Jarod Elliott提出了一种更好的策略来检查mod是否产生任何东西。
int result = (int1 / int2);
if (int1 % int2 != 0) { result++; }
我将此循环运行了100万次,耗时8ms。这是使用 Math 的代码:
int result = (int)Math.Ceiling((double)int1 / (double)int2);
在我的测试中,哪一次跑了14毫秒?
答案 10 :(得分:1)
我执行以下操作,处理任何溢出:
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;
答案 11 :(得分:0)
替代在测试零时删除分支:
int pageCount = (records + recordsPerPage - 1) / recordsPerPage * (records != 0);
不确定这是否适用于C#,应该用C / C ++。
答案 12 :(得分:0)
对于C#,请使用Math.Ceiling函数:
var pageCount= Math.Ceiling((double)myList.Count() / recordsPerPage);
和Java使用Math.Ceil函数:
int n = (int) Math.ceil((double)myList.size() / recordsPerPage));
答案 13 :(得分:-1)
一个通用方法,你可以迭代它的结果可能是有意义的:
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;
}
答案 14 :(得分:-2)
我有类似的需求,我需要将分钟转换为小时和分钟。我用的是:
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);
答案 15 :(得分:-2)
以下应该比上述解决方案更好地舍入,但是以牺牲性能为代价(由于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;
}
答案 16 :(得分:-4)
您需要进行浮点除法,然后使用ceiling函数将值向上舍入为下一个整数。