如何总是舍入到下一个整数
我想在网站上build立一个寻呼机的总页(所以我想要的结果是一个整数。我得到一个logging列表,我想分成10每页(页数)
当我这样做:
list.Count() / 10
要么
list.Count() / (decimal)10
和list.Count() =12
,我得到1的结果。
我将如何编码,所以我得到2
在这种情况下(其余的应该总是加1
)
Math.Ceiling((double)list.Count() / 10);
(list.Count() + 9) / 10
这里的其他一切都是矫枉过正的,或者只是错误的(除了bestsss的答案 ,这是真棒)。 当简单的math运算就足够了的时候,我们不需要函数调用( Math.Truncate()
, Math.Ceiling()
等)的开销。
OP的问题概括( 鸽子的原理 )为:
如果只有
y
对象放入每个盒子,我需要多less个盒子才能存储x
对象?
解决scheme:
- 来自最后一个盒子可能部分空的认识,并且
- 是使用整数除法的
(x + y - 1) ÷ y
。
你会记得从三年级的math,当我们说5 ÷ 2 = 2
时, 整数除法是我们正在做的事情。
浮点除法是当我们说5 ÷ 2 = 2.5
,但我们不想在这里。
许多编程语言都支持整数除法。 在从C派生的语言中,当你划分int
types( short
, int
, long
等)的时候会自动得到它。 任何除法运算的余数/小数部分都被简单地删除,因此:
5 / 2 == 2
用x = 5
和y = 2
代替原来的问题,我们有:
如果每个盒子只装入两个物品,我需要多less个盒子来存放5个物品?
答案现在应该是显而易见的: 3 boxes
– 前两盒分别容纳两个对象,最后一盒容纳一个。
(x + y - 1) ÷ y = (5 + 2 - 1) ÷ 2 = 6 ÷ 2 = 3
所以对于原来的问题, x = list.Count()
, y = 10
,这样就不需要额外的函数调用:
(list.Count() + 9) / 10
这也将工作:
c = (count - 1) / 10 + 1;
一个合适的benchamrk或如何数字可能是谎言
在关于Math.ceil(value/10d)
和(value+9)/10
的争论之后,我最终编写了一个适当的非死代码,非解释模式基准。 我已经告诉过,拧微标准并不是一件容易的事情。 下面的代码说明。
开始结果
00:21:40.109启动.... 00:21:40.140 doubleCeil:19444599 00:21:40.140 integerCeil:19444599 00:21:40.140热身 00:21:44.375热身doubleCeil:194445990000 00:21:44.625热身integerCeil:194445990000 00:22:27.437 exec doubleCeil:1944459900000, 耗时:42.806s 00:22:29.796 exec integerCeil:1944459900000, 过去了:2.363s
基准是用Java编写的,因为我很了解Hotspot如何优化,并确保它是一个公平的结果。 有了这样的结果,没有统计数据,噪音或任何东西都可以染色。
整数类似的小区疯狂地快得多。
代码
package t1; import java.math.BigDecimal; import java.util.Random; public class Div { static int[] vals; static long doubleCeil(){ int[] v= vals; long sum = 0; for (int i=0;i<v.length;i++){ int value = v[i]; sum+=Math.ceil(value/10d); } return sum; } static long integerCeil(){ int[] v= vals; long sum = 0; for (int i=0;i<v.length;i++){ int value = v[i]; sum+=(value+9)/10; } return sum; } public static void main(String[] args) { vals = new int[7000]; Random r= new Random(77); for (int i = 0; i < vals.length; i++) { vals[i] = r.nextInt(55555); } log("starting up...."); log("doubleCeil: %d", doubleCeil()); log("integerCeil: %d", integerCeil()); log("warming up..."); final int warmupCount = (int) 1e4; log("warmup doubleCeil: %d", execDoubleCeil(warmupCount)); log("warmup integerCeil: %d", execIntegerCeil(warmupCount)); final int execCount = (int) 1e5; { long time = System.nanoTime(); long s = execDoubleCeil(execCount); long elapsed = System.nanoTime() - time; log("exec doubleCeil: %d, elapsed: %.3fs", s, BigDecimal.valueOf(elapsed, 9)); } { long time = System.nanoTime(); long s = execIntegerCeil(execCount); long elapsed = System.nanoTime() - time; log("exec integerCeil: %d, elapsed: %.3fs", s, BigDecimal.valueOf(elapsed, 9)); } } static long execDoubleCeil(int count){ long sum = 0; for(int i=0;i<count;i++){ sum+=doubleCeil(); } return sum; } static long execIntegerCeil(int count){ long sum = 0; for(int i=0;i<count;i++){ sum+=integerCeil(); } return sum; } static void log(String msg, Object... params){ String s = params.length>0?String.format(msg, params):msg; System.out.printf("%tH:%<tM:%<tS.%<tL %s%n", new Long(System.currentTimeMillis()), s); } }
我认为最简单的方法是将两个整数相加并加1:
int r = list.Count() / 10; r += (list.Count() % 10 == 0 ? 0 : 1);
不需要图书馆或function。
用正确的代码编辑。
使用mod检查 – 如果有余数,只需将值加1。
Xform加倍(和回)一个简单的小游戏?
list.Count()/10 + (list.Count()%10 >0?1:0)
– 这个不好的,div + mod
编辑第一:在2n认为可能更快(取决于优化):div * mul(mul比div和mod更快)
int c=list.Count()/10; if (c*10<list.Count()) c++;
编辑2全部。 忘了最自然的(加9就保证整数的四舍五入)
(list.Count()+9)/10