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

leo*_*ora 81 c# language-agnostic rounding

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

当我这样做:

list.Count() / 10
Run Code Online (Sandbox Code Playgroud)

要么

list.Count() / (decimal)10
Run Code Online (Sandbox Code Playgroud)

而且list.Count() =12,我得到了结果1.

我将如何编码,以便2在这种情况下得到它(其余部分应该总是添加1)

Rob*_*Rob 167

Math.Ceiling((double)list.Count() / 10);
Run Code Online (Sandbox Code Playgroud)

  • 这些家伙抱怨分页公式的基准...... Rob的回答是最好的.它干净简单,你在一些迭代中不会处理数百次...一旦你有了一个列表,你只需要知道页面的数量,这种类型转换从int到double到int的转换是纳秒时间这将加起来可能在第二天分裂.不值得花时间甚至诚实地回应这篇评论.有时甚至毫秒加在这里或者值得简单. (13认同)
  • 对于这样一个简单的操作,将int转换为浮点只是坏(和慢) (5认同)
  • @Rob - 差异不仅仅在于浮点转换,你还有额外的函数调用开销用于调用Ceiling().这不是"额外的可读性",而是"额外的工作",并且*不是*正确的方法.这个问题在SO上一遍又一遍地被问到,并且有一个更好的解决方案,不涉及类型转换,也没有额外的功能调用.新程序员需要学会以正确的方式去做.事实证明,正确地做到这一点是非常易读的,并且看到有人做错了,所以他们的所有代码都会受到质疑. (4认同)
  • 100万次循环的执行时间差异为0.01ms.我认为处理时间这种可忽略不计的增加的额外可读性是值得的. (3认同)
  • @Rob,你做...两次,int->floating point(double)->int。它需要对 CPU 进行两次刷新,解决方案是最坏的正确方法(对于 int 但不长) (2认同)

par*_*par 61

(list.Count() + 9) / 10

这里的其他所有事情都是矫枉过正或者是错误的(除了优秀的答案,这很棒).当简单的数学运算足够时,我们希望函数调用(等)的开销.Math.Truncate()Math.Ceiling()


OP的问题概括(归类原则):

x如果只有y对象放入每个盒子,我需要多少盒来存储对象?

解决方案:

  1. 源于认识到最后一个框可能部分为空,并且
  2. 正在(x + y - 1) ÷ y使用整数除法.

你会从3回顾第三年级的数学是整数除法是,当我们说我们正在做的事情5 ÷ 2 = 2.

浮点除法是我们说的5 ÷ 2 = 2.5,但我们希望这里.

许多编程语言都支持整数除法.在衍生自C语言中,你会自动获得它,当你把int类型(short,int,long等).简单地删除任何除法运算的余数/小数部分,因此:

5 / 2 == 2

与更换我们最初的问题x = 5y = 2我们有:

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

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

(x + y - 1) ÷ y =
(5 + 2 - 1) ÷ 2 =
6 ÷ 2 =
3
Run Code Online (Sandbox Code Playgroud)

因此,对于原来的问题,x = list.Count(),y = 10,这给不使用额外的函数调用的解决方案:

(list.Count() + 9) / 10

  • 很好的解释 (3认同)
  • 你的陈述是错误的(实际上是 23,这正是我们想要的)。请参阅我修改后的答案。 (2认同)
  • 我无法理解为什么这个答案没有得到更多的认可。这是迄今为止最优雅的解决方案。 (2认同)

bes*_*sss 20

一个适当的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
Run Code Online (Sandbox Code Playgroud)

该基准测试使用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);
    }   
}
Run Code Online (Sandbox Code Playgroud)


fin*_*nnw 17

这也有效:

c = (count - 1) / 10 + 1;
Run Code Online (Sandbox Code Playgroud)


Rad*_*iev 5

我认为最简单的方法是将两个整数相除并加一:

int r = list.Count() / 10;
r += (list.Count() % 10 == 0 ? 0 : 1);
Run Code Online (Sandbox Code Playgroud)

不需要库或函数。

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