Cómo redondear con la división de enteros en C

Para calcular (x*y)/z con redondeo ascendente suponiendo x , y y z positivo y suponiendo que (x*y) no se desborda:

int resultado = (x * y-1) / z + 1;

Este método evita desbordamientos (distintos de los que ya pueden estar presentes en x*y ).

Si usa la alternativa r = (x*y+(z-1))/z; luego agregar el (z-1) puede causar un desbordamiento, mientras que la primera solución no lo hará.

Donde x*y es negativo, o z es negativo, entonces necesita ajustar de acuerdo con el comportamiento que desee. Lamentablemente, C y otros lenguajes difieren de la forma en que a los matemáticos les gustaría hacer esto.

Si el resultado se ajusta dentro de un int , es posible que el valor intermedio x*y se desborde. Esto se puede evitar de la siguiente manera:

int resultado = (x / z) * y + ((x% z) * y-1) / z + 1;

Nuevamente, modifique esto de acuerdo a sus necesidades si uno de x*y o z es negativo.

Es fácil si se trata de números positivos.

int v = (x * y + 5) / 10;

Con números negativos no funciona porque la división en C es incorrecta desde el punto de vista aritmético

En matemáticas (-1) / 10 es -1 con el resto 9. En C (-1) / 10 = 0 y (-1)% 10 = -1.

Math elige de manera uniforme una opción más pequeña entre dos posibilidades, C elige una implementada por un ingeniero de hardware que no encontró nada mejor que voltear el letrero, realizar la operación y luego voltear el letrero nuevamente.

El código universal es más complicado:

int res;

v = x * y;

si (v> = 0) res = (v + 5) / 10;

más resultados = (v – 5) / 10;

A veces estoy usando una forma “sucia”:

int v = (x * y + 5 + GRANDE * 10) / 10 – GRANDE;

GRANDE es un número suficientemente grande. Está sucio, pero funciona más rápido que la lógica, las ramas son operaciones más lentas. No debe usarlo a menos que realmente necesite optimizar el código.