cómo redondear siempre al siguiente entero [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Estoy tratando de encontrar páginas totales en la construcción de un buscapersonas en un sitio web (por lo que quiero que el resultado sea un entero. obtengo una lista de registros y quiero dividir en 10 por página (el recuento de páginas)

Cuando lo hago esto:

list.Count() / 10

O

list.Count() / (decimal)10

Y el list.Count() =12, obtengo un resultado de 1.

Cómo lo codificaría para obtener 2 en este caso (el resto siempre debe agregar 1)

Author: bestsss, 2011-01-31

8 answers

Math.Ceiling((double)list.Count() / 10);
 144
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-31 00:06:39

(list.Count() + 9) / 10

Todo lo demás aquí es exagerado o simplemente incorrecto (excepto por la respuesta de bestsss, que es impresionante). Lo hacemosno desea la sobrecarga de una llamada a una función(Math.Truncate(), Math.Ceiling(), etc.) cuando la matemática simple es suficiente.


La pregunta de OP generaliza (principio de casillero) a:

¿Cuántas cajas necesito para almacenar x objetos si solo y los objetos caben en cada caja?

El solución:

  1. se deriva de la comprensión de que la última caja podría estar parcialmente vacía, y{[47]]}
  2. es (x + y - 1) ÷ yusando división entera.

Recordarás de 3 rdmatemáticas de grado que división de enteros es lo que estamos haciendo cuando decimos 5 ÷ 2 = 2.

La división en coma flotante es cuando decimos 5 ÷ 2 = 2.5, pero no lo hagas quiero eso aquí.

Muchos lenguajes de programación admiten integer Division. En lenguajes derivados de C, se obtiene automáticamente cuando se dividen los tipos int (short, int, long, etc.). El resto/parte fraccionaria de cualquier operación de división simplemente se elimina, así:

5 / 2 == 2

Reemplazando nuestra pregunta original con x = 5 y y = 2 tenemos:

¿Cuántas cajas necesito para almacenar 5 objetos si solo caben 2 objetos en cada caja?

La respuesta ahora debería ser obvia: 3 boxes the las dos primeras cajas contienen dos objetos cada uno y la última caja contiene uno.

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

Así que para la pregunta original, x = list.Count(), y = 10, lo que da la solución sin llamadas a funciones adicionales:

(list.Count() + 9) / 10

 48
Author: par,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:25

Un benchamrk apropiado o cómo el número puede estar

Siguiendo el argumento sobre Math.ceil(value/10d) y (value+9)/10 terminé codificando un código no muerto adecuado, un benchmark de modo no interpretativo. He estado diciendo que wring micro benchmark no es una tarea fácil. El siguiente código ilustra.
Inicio de los resultados

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

El punto de referencia está en Java, ya que sé bien cómo optimiza Hotspot y me aseguro de que sea un resultado justo. Con tales resultados, ninguna estadística, ruido o nada puede teñirlo.

Integer alike ceil es increíblemente mucho más rápido.

El código

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);
    }   
}
 19
Author: bestsss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-03 22:29:13

Esto también funcionará:

c = (count - 1) / 10 + 1;
 17
Author: finnw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-31 18:18:05
 3
Author: mfanto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-31 00:07:17

Creo que la forma más fácil es dividir dos enteros y aumentar por uno:

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

No hay necesidad de bibliotecas o funciones.

Editado con el código correcto.

 3
Author: Radoslav Georgiev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-31 00:25:22

Compruebe usando mod - si hay un resto, simplemente incremente el valor en uno.

 0
Author: Den Delimarsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-31 00:07:29

Xform para doblar (y volver) para un techo simple?

list.Count()/10 + (list.Count()%10 >0?1:0) - este mal, div + mod

Editar 1ª: en un pensamiento 2n que es probablemente más rápido (depende de la optimización): div * mul (mul es más rápido que div y mod)

int c=list.Count()/10;
if (c*10<list.Count()) c++;

Edit2 scarpe all. olvidó el más natural (la adición de 9 asegura el redondeo para los enteros)

(list.Count()+9)/10

 0
Author: bestsss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-31 00:24:20