Maison >développement back-end >C++ >Pourquoi le dépassement d'entier produit-il des résultats inattendus en C ?

Pourquoi le dépassement d'entier produit-il des résultats inattendus en C ?

DDD
DDDoriginal
2024-11-12 16:47:01265parcourir

Why Does Integer Overflow Produce Unexpected Results in C  ?

Résultats inattendus avec un débordement d'entier en C

Lorsque vous travaillez avec des types entiers, il est essentiel de comprendre les implications du débordement. Dans cet article, nous explorons pourquoi les dépassements d'entiers signés et non signés donnent des résultats inattendus dans un programme C.

Considérez le programme suivant qui teste le dépassement d'entier :

#include <iostream>

int main()
{
    int x(0);
    std::cout << x << std::endl;

    x = x + 2147483647;
    std::cout << x << std::endl;

    x = x + 1;
    std::cout << x << std::endl;
    std::cout << std::endl;

    unsigned int y(0);
    std::cout << y << std::endl;

    y = y + 4294967295;
    std::cout << y << std::endl;

    y = y + 1;
    std::cout << y << std::endl;
}

Le résultat est surprenant :

0
2147483647
-2147483648

0
4294967295
0

Entier signé Débordement

Le débordement d'entier signé est un comportement indéfini. Cela signifie que le compilateur peut faire tout ce qu'il veut, y compris produire un résultat incorrect comme dans ce cas.

Dépassement d'entier non signé

En revanche, le dépassement d'entier non signé est bien -défini. La valeur s'enroule, comme une division modulo par 2^bits (où bits est le nombre de bits dans le type de données). Puisque nous avons un int 32 bits :

4294967295 + 1 = 4294967296 % 2^32 = 0

Détails d'implémentation spécifiques

Même si le dépassement d'entier signé est un comportement non défini, la plupart des implémentations utilisent la représentation du complément à 2. Ceci explique les résultats spécifiques observés dans ce programme :

  • POS_MAX (valeur positive maximale) = 7 (0111)
  • NEG_MAX (valeur négative maximale) = -8 (1000)

Lorsque vous ajoutez 1 à POS_MAX :

0111 + 1 = 1000

Puisque le bit de début est défini, c'est un nombre négatif. Pour trouver la valeur réelle, nous effectuons l'inverse du complément à 2 :

1000 - 1 = 0111
~0111 = 1000 = -8

Ainsi, la valeur finale est -8, qui apparaît dans la sortie du programme.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn