如何总是向上舍入到下一个整数

时间:2011-01-31 00:05:45

标签: c# language-agnostic rounding

我试图找到在网站上构建寻呼机的总页数(所以我希望结果是一个整数。我得到一个记录列表,我想分成10页/页(页数)

当我这样做时:

list.Count() / 10

list.Count() / (decimal)10

list.Count() =12,我得到1的结果。

我如何对其进行编码,以便在这种情况下获得2(其余部分应始终添加1

8 个答案:

答案 0 :(得分:157)

Math.Ceiling((double)list.Count() / 10);

答案 1 :(得分:56)

(list.Count() + 9) / 10

这里的其他所有内容都是矫枉过正或完全错误(bestsss' answer除外,这很棒)。当简单数学足够时,我们 需要函数调用(Math.Truncate()Math.Ceiling()等)的开销。


OP的问题将(pigeonhole principle)概括为:

  

如果只有x个对象放入每个框中,我需要多少个框才能存储y个对象?

解决方案:

  1. 源于认识到最后一个框可能部分为空,并且
  2. (x + y - 1) ÷ y使用integer division
  3. 您将从3 rd 等级数学中回忆起当我们说5 ÷ 2 = 2整数除法是我们正在做的事。

    浮点除法是我们说5 ÷ 2 = 2.5的时候,但我们 想要这个。

    许多编程语言都支持整数除法。在从C派生的语言中,您可以在划分int类型(shortintlong等时自动获取它。简单地删除任何除法运算的余数/小数部分,因此:

    5 / 2 == 2

    用我们的x = 5y = 2替换原来的问题:

      

    如果每个盒子中只有2个物体,我需要多少个盒子才能存储5个物体?

    答案现在应该是显而易见的:3 boxes - 前两个框每个都有两个对象,最后一个框有一个。

    (x + y - 1) ÷ y =
    (5 + 2 - 1) ÷ 2 =
    6 ÷ 2 =
    3
    

    因此对于原始问题x = list.Count()y = 10,它提供的解决方案不使用其他函数调用:

    (list.Count() + 9) / 10

答案 2 :(得分:19)

适当的benchamrk或数字可能如何

在关于Math.ceil(value/10d)(value+9)/10的争论之后,我最终编写了一个适当的非死代码,非解释模式基准。 我一直在说,拧微基准并不是一件容易的事。下面的代码说明。
开始结果

00:21:40.109 starting up....
00:21:40.140 doubleCeil: 19444599
00:21:40.140 integerCeil: 19444599
00:21:40.140 warming up...
00:21:44.375 warmup doubleCeil: 194445990000
00:21:44.625 warmup integerCeil: 194445990000
00:22:27.437 exec doubleCeil: 1944459900000, elapsed: 42.806s
00:22:29.796 exec integerCeil: 1944459900000, elapsed: 2.363s

基准测试是用Java编写的,因为我很清楚Hotspot如何优化并确保它是一个公平的结果。有了这样的结果,没有统计数据,噪音或任何东西可以染色。

整数相似的ceil非常快。

代码

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

答案 3 :(得分:17)

这也有效:

c = (count - 1) / 10 + 1;

答案 4 :(得分:3)

答案 5 :(得分:3)

我认为最简单的方法是划分两个整数并增加一个:

int r = list.Count() / 10;
r += (list.Count() % 10 == 0 ? 0 : 1);

不需要库或函数。

使用正确的代码进行编辑。

答案 6 :(得分:0)

使用mod进行检查 - 如果有余数,只需将值递增1。

答案 7 :(得分:0)

Xform为一个简单的ceil加倍(和后退)?

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

edit2 scarpe all。忘记了最自然的(添加9确保整数的整数)

(list.Count()+9)/10