Saltar al contenido

Redondeo de división de enteros (en lugar de truncamiento)

Te damos la bienvenida a nuestra web, ahora vas a encontrar la respuesta a lo que necesitas.

Solución:

El idioma estándar para el redondeo de enteros es:

int a = (59 + (4 - 1)) / 4;

Sumas el divisor menos uno al dividendo.

Un código que funciona para cualquier signo de dividendo y divisor:

int divRoundClosest(const int n, const int d)

  return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d);

En respuesta a un comentario "¿Por qué funciona esto realmente?", podemos desglosarlo. Primero, observa que n/d sería el cociente, pero se trunca hacia cero, no se redondea. Obtienes un resultado redondeado si sumas la mitad del denominador al numerador antes de dividir, pero solo si el numerador y el denominador tienen el mismo signo. Si los signos difieren, debes restar la mitad del denominador antes de dividir. Poniendo todo eso junto:

(n < 0) is false (zero) if n is non-negative
(d < 0) is false (zero) if d is non-negative
((n < 0) ^ (d < 0)) is true if n and d have opposite signs
(n + d/2)/d is the rounded quotient when n and d have the same sign
(n - d/2)/d is the rounded quotient when n and d have opposite signs

Si prefieres un macro:

#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) ^ ((d) < 0)) ? (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d)))

el kernel de linux macro ¡DIV_ROUND_CLOSEST no funciona para divisores negativos!

EDITAR: Esto funcionará sin desbordamiento:

int divRoundClosest( int A, int B )

if(A<0)
    if(B<0)
        return (A + (-B+1)/2) / B + 1;
    else
        return (A + ( B+1)/2) / B - 1;
else
    if(B<0)
        return (A - (-B+1)/2) / B - 1;
    else
        return (A - ( B+1)/2) / B + 1;

int a = 59.0f / 4.0f + 0.5f;

Esto solo funciona cuando se asigna a un int, ya que descarta cualquier cosa después del '.'

Editar:
Esta solución solo funcionará en los casos más simples. Una solución más robusta sería:

unsigned int round_closest(unsigned int dividend, unsigned int divisor)

    return (dividend + (divisor / 2)) / divisor;

Te mostramos las comentarios y valoraciones de los usuarios

Si estás contento con lo expuesto, eres capaz de dejar un tutorial acerca de qué le añadirías a esta crónica.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *