La détection de débordement portable la plus efficace?

Dupliquer possible:
multiplication de grands nombres, comment attraper le débordement

Dans les langages métalliques comme C, C ++ et D, quel est le moyen le plus efficace et portable (c’est-à-dire sans assembleur, bien que vous puissiez supposer un comportement arithmétique et complémentaire à deux) pour détecter le débordement d’un non signé entier sur multiplication?

Vous pouvez détecter le débordement à l’avance en divisant la valeur maximale pouvant être représentée par le type non signé par l’un des multiplicandes; si le résultat est inférieur à l’autre multiplicande, sa multiplication entraînerait une valeur dépassant la plage du type non signé.

Par exemple, en C ++ (à l’aide des types numériques C ++ 0x à largeur exacte):

std::uint64_t left = 12; std::uint64_t right = 42; if (left != 0 && (std::numeric_limits::max() / left) < right) { // multiplication would exceed range of unsigned } 

En C, vous pouvez utiliser uint64_t pour le type et UINT64_MAX pour la valeur maximale. Ou, si vous vous souciez seulement que le type ait au moins 64 bits et pas nécessairement 64 bits, vous pouvez utiliser unsigned long long et ULLONG_MAX .

Il y a quelques réponses à cette question presque en double . Cette réponse devrait fonctionner en C, C ++ et dans d’autres langages similaires:

 if (b > 0 && a > 18446744073709551615 / b) { // overflow handling } else { c = a * b; } 

Ou cette réponse qui effectue la multiplication puis divise le résultat par l’un des arguments pour voir si elle est égale à l’autre:

 x = a * b; if (a != 0 && x / a != b) { // overflow handling } 

Il existe probablement des méthodes plus efficaces, mais c’est un moyen facile et portable de le faire:

 // assume 'a' and 'b' are the operands to be multiplied if( ( a != 0 ) && ( UINT64_MAX / a ) < b ) ) { // overflow }