当前位置:  开发笔记 > 编程语言 > 正文

如何整理整数除法的结果?

如何解决《如何整理整数除法的结果?》经验,为你挑选了6个好方法。

在使用C#或Java等语言时,我正在考虑如何显示分页控件.

如果我想要以每页y块的形式显示x项,那么需要多少页?



1> Ian Nelson..:

找到优雅的解决方案:

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

资料来源:编号转换,Roland Backhouse,2001年


Obvious先生说:记住要确保recordsPerPage不为零
-1因为[Brandon DuRette]指出的溢出错误(http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division/96921#96921)
干得好,我不敢相信C#没有整数上限.
是的,在这里,我在2017年中期在尝试了几个更复杂的方法后遇到了这个伟大的答案.

2> rjmunro..:

转换为浮点和返回似乎是CPU级别的大量浪费时间.

伊恩·尼尔森的解决方案:

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

可以简化为:

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

AFAICS,这没有Brandon DuRette指出的溢出错误,并且因为它只使用它一次,如果它来自一个昂贵的函数来从配置文件中获取值,则不需要特别存储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;


请注意,这两个解决方案不会为零记录返回相同的pageCount.此简化版本将返回1 pageCount为零记录,而Roland Backhouse版本返回0 pageCount.如果这是你想要的,那很好,但是当用C#/ Java样式整数除法执行时,这两个等式不相等.
从Nelson解决方案改为简化时,人们扫描它和丢失的bodmas的清晰度很小(就像我第一次做的那样!),括号的简化是... int pageCount =((records-1)/ recordsPerPage) + 1;
+1,零记录仍然返回1 pageCount的问题实际上很方便,因为我仍然想要1页,显示"没有记录符合你的标准"的占位符/假行,有助于避免任何"0页计数"问题你使用的分页控制.

3> Huppie..:

对于C#,解决方案是将值转换为double(因为Math.Ceiling需要一个double):

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

在java中,您应该对Math.ceil()执行相同的操作.


因为效率极低
它可能效率低下但很容易理解.鉴于计算页数通常每次请求一次,任何性能损失都无法衡量.
除非是快速循环,否则我会快速阅读.
当op明确要求C#时,为什么这个答案到目前为止呢?
你还需要将输出转换为`int`,因为`Math.Ceiling`返回一个`double`或`decimal`,具体取决于输入类型.

4> Nick Berardi..:

这应该给你你想要的.您肯定希望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);


x/y + !!(x%y)避免了类C语言的分支.可能性很好,但是,无论如何,你的编译器正在这样做.
像上面的答案一样没有溢出的+1 ...尽管将ints转换为仅为Math.ceiling而再返回的双打在性能敏感代码中是一个坏主意.
@RhysUlerich在c#中不起作用(不能直接将int转换为bool).rjmunro的解决方案是我认为避免分支的唯一方法.

5> Brandon DuRe..:

Ian提供的整数数学解决方案很好,但是遇到整数溢出错误.假设变量都是变量int,可以重写解决方案以使用long数学并避免错误:

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

如果recordslong,则错误仍然存​​在.模数解决方案没有错误.


@rjmunro,[这里的真实示例](http://code.google.com/p/guava-libraries/issues/detail?id=616)
是的,我在指出这个错误时很迂腐.许多错误可以永久存在而不会造成任何问题.在有人报告它之前,JDK实现binarySearch已存在相同形式的错误九年(http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly的.html).我想问题是,不管你遇到这个bug的可能性有多大,为什么不预先修好呢?
我不认为你在实际情况中会遇到这个错误.2 ^ 31条记录需要翻页.
此外,应该注意的是,不仅仅是分页的元素数量,它也是页面大小.因此,如果您正在构建库并且有人选择不通过传递2 ^ 31-1(Integer.MAX_VALUE)作为页面大小来进行分页,则会触发该错误.

6> finnw..:

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

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增加1 if的效果records % recordsPerPage > 0.

推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有