you with ver traduction traducida traduccion the sunset strong seen see right rain quiero person peace now not never means may many make love learning learned laugh ingles how have give first feel fail end but because attempt and alone all c++ long-long

c++ - with - ¿Cómo comprobar si A+B superan largo tiempo?(Tanto A como B son largas largas)



quiero ver en ingles (4)

Además, si solo lo está utilizando para la depuración, puede usar el siguiente ''truco'' para leer el bit de desbordamiento de la última operación directamente (suponiendo que su compilador / CPU admita esto):

int flags; _asm { pushf // push flag register on the stack pop flags // read the value from the stack } if (flags & 0x0800) // bit 11 - overflow ...

Esta pregunta ya tiene una respuesta aquí:

Tengo 2 números: A y B Necesito calcular A+B en algún lugar de mi código. Tanto A como B son long long , y pueden ser positivos o negativos .

Mi código se ejecuta de forma incorrecta y sospecho que el problema ocurre al calcular A+B Simplemente quiero comprobar si A+B excede el long long alcance. Por lo tanto, cualquier método es aceptable, ya que solo lo uso para la depuración.


Algo como lo siguiente:

long long max = std::numeric_limits<long long>::max(); long long min = std::numeric_limits<long long>::min(); if(A < 0 && B < 0) return B < min - A; if(A > 0 && B > 0) return B > max - A; return false;

Podemos razonar sobre esto de la siguiente manera:

  • Si A y B son signos opuestos, no pueden desbordarse: el mayor que cero debería ser mayor que el max o el menor que cero debería ser menor que el min .

  • En los otros casos, basta con el álgebra simple. A + B > max => B > max - A se desbordará si ambos son positivos. De lo contrario, si ambos son negativos, A + B < min => B < min - A


El desbordamiento es posible solo cuando ambos números tienen el mismo signo. Si ambos son positivos, entonces tiene un desbordamiento si matemáticamente A + B > LLONG_MAX , o equivalentemente B > LLONG_MAX - A Como el lado derecho no es negativo, la última condición ya implica B > 0 . El argumento análogo muestra que, en el caso negativo, tampoco es necesario verificar el signo de B (gracias a Ben Voigt por señalar que el control de signos en B es innecesario). Entonces puedes comprobar

if (A > 0) { return B > (LLONG_MAX - A); } if (A < 0) { return B < (LLONG_MIN - A); } return false;

para detectar el desbordamiento. Estos cálculos no pueden desbordarse debido a las comprobaciones iniciales.

Verificar el signo del resultado de A + B funcionaría con la semántica envolvente garantizada de los cálculos de enteros desbordados. Pero el desbordamiento de enteros con signo es un comportamiento indefinido, e incluso en las CPU en las que la envoltura es el comportamiento implementado, el compilador puede asumir que no ocurre un comportamiento indefinido y eliminar la verificación de desbordamiento cuando se implementa de esta manera. Así que el cheque sugerido en los comentarios a la pregunta es altamente poco confiable.


Enmascare los signos, conviértalos a valores sin firmar y realice la suma. Si está por encima de 1 << (sizeof(int) * 8 - 1) entonces tiene un desbordamiento.

int x, y; if (sign(x) == sign(y)){ unsigned int ux = abs(x), uy = abs(y); overflow = ux + uy >= (1 << (sizeof(int) * 8 - 1)); }

Mejor aún, vamos a escribir una plantilla:

template <typename T> bool overflow(signed T x, signed T y){ unsigned T ux = x, uy = y; return ( sign(x) == sign(y) && (ux + uy >= (1 << (sizeof(T) * 8 - 1))); }