C# 如何始终向上取整到下一个整数

C# 如何始终向上取整到下一个整数,c#,language-agnostic,rounding,C#,Language Agnostic,Rounding,我试图在网站上构建寻呼机时查找总页面数(因此我希望结果是一个整数。我得到一个记录列表,并希望将每页分成10页(页面计数) 当我这样做时: list.Count() / 10 或 而list.Count()=12,我得到的结果是1 在这种情况下,我应该如何编码才能得到2(剩余部分应始终添加1)您可以使用Math 使用mod检查-如果有余数,只需将该值增加1即可。对于简单的ceil,是否转换为双倍(并返回) list.Count()/10+(list.Count()%10>0?1:0)-这很糟糕,

我试图在网站上构建寻呼机时查找总页面数(因此我希望结果是一个整数。我得到一个记录列表,并希望将每页分成10页(页面计数)

当我这样做时:

list.Count() / 10

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


在这种情况下,我应该如何编码才能得到
2
(剩余部分应始终添加
1

您可以使用Math


使用mod检查-如果有余数,只需将该值增加1即可。

对于简单的ceil,是否转换为双倍(并返回)

list.Count()/10+(list.Count()%10>0?1:0)
-这很糟糕,div+mod

第一次编辑: 根据2n的想法,这可能更快(取决于优化):div*mul(mul比div和mod快)

int c=list.Count()/10;

如果(c*10我认为最简单的方法是将两个整数除以一:

int r = list.Count() / 10;
r += (list.Count() % 10 == 0 ? 0 : 1);
不需要库或函数

使用正确的代码编辑。

(list.Count()+9)/10

这里的其他一切要么是矫枉过正,要么就是完全错误(除了,这太棒了)。当简单的数学足够时,我们确实不想要函数调用的开销(
Math.Truncate()
Math.天花()
,等等)


OP的问题将()概括为:

如果每个框中只包含
y
对象,我需要存储多少个
x
对象

解决方案:

  • 源自最后一个框可能部分为空的认识,以及
  • (x+y-1)÷y
    使用
  • 你会记得,从三年级的数学中,当我们说
    5÷2=2
    时,整数除法就是我们要做的

    浮点除法是指我们说的
    5÷2=2.5
    ,但我们不想在这里使用它

    许多编程语言支持整数除法。在从C派生的语言中,当您对
    int
    类型(
    short
    int
    long
    等)进行除法时,会自动获得整数除法。任何除法运算的余数/小数部分都会被简单地删除,因此:

    5/2==2

    将原来的问题替换为
    x=5
    y=2
    我们有:

    如果每个盒子中只有2个对象,我需要多少个盒子来存储5个对象

    答案现在应该是显而易见的:
    3个框
    ——前两个框分别容纳两个对象,最后一个框容纳一个对象

    (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;
    
    一个合适的基准或数字可能如何 在关于
    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是如何优化的,并确保它是一个公平的结果

    Integer 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);
        }   
    }
    
    t1包;
    导入java.math.BigDecimal;
    导入java.util.Random;
    公共课组{
    静态int[]vals;
    静态长双细胞(){
    int[]v=VAL;
    长和=0;
    
    对于(int i=0;i(list.Count()+9)/10-这是最好的:)Math.Round(8.28,0,middpointrounding.AwayFromZero)将int转换为浮点对于这样一个简单的operation@Rob,您可以执行..两次,int->floating point(double)->int。它需要CPU的双重刷新,解决方案可能是最差的正确方案(对于int,但不长)一百万个周期的执行时间之差为0.01ms。我认为处理时间的微小增加带来的额外可读性是值得的。@Rob-差异不仅仅在于浮点转换,还包括对上限()调用的额外函数调用开销。这不是“额外可读性”,而是“额外工作"这不是正确的方法。这个问题会被无数次地问到,因此有一个更好的解决方案,它不涉及类型转换和额外的函数调用。新程序员需要学习正确的方法。事实证明,正确地做这件事是很容易理解的,看到有人做错事会调用所有的函数他们的代码成了问题。这些家伙在抱怨分页公式的基准测试…Rob的答案是最佳人选。它干净简单,而且你不会在某个迭代中处理数百次…一旦你有了一个列表,你只需要知道页数,这种从int到double再到int的类型转换麻烦只需要纳秒总有一天可能会有一瞬间。甚至不值得花时间诚实地写下此评论作为回应。有时甚至在此处或此处添加毫秒也值得简化。当计数%10==0时,这不会正常工作。即,如果list.count()返回2表示10不正确==除法前的10。当1正确时,你得到2。哎呀,错过了。你们是对的,伙计:)你必须先做mod,然后进行测试,然后进行增量(这是一个加法和一个存储)。太贵了。只做加法然后除法更容易(和mod一样贵)。无需测试。回答很好。断言是一回事,证明完全是另一回事。好的一点,证明是另一回事。我认为你的代码有很多问题,特别是像0和20这样的数字(将返回3)或者任何大于10的数字。@Rumplin,您对0的估计是正确的,但对于20,它会返回预期的2。您是对的,对于数字>0,它可以正常工作。这是一个很好的解决方案,但在我看来,这比使用Math.天花板可读性差。乍一看,不清楚代码是什么
    c = (count - 1) / 10 + 1;
    
    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
    
    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);
        }   
    }