Question

Ce qui se passe réellement lorsqu'un Octet débordements?

Disons que nous avons

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

Si, maintenant, nous n'cet ajout

byte byte3 = byte1 + byte2;

Je pense que nous finirons avec octet 3 = 94 mais ce qui se passe réellement?Ai-je remplacer certains autres de la mémoire, d'une manière ou est-ce totalement inoffensif?

Était-ce utile?

La solution

Il est tout à fait simple. Il fait juste l'addition et se détache à un certain nombre avec plus de 8 bits. Le neuvième bit (soit un) juste « tombe » et on se retrouve avec les 8 bits restants qui forment le nombre 94.

(oui il est inoffensif)

Autres conseils

En C # si vous avez

 checked { byte byte3 = byte1 + byte2; }

Il lancera une exception de débordement. Le code est compilé unchecked par défaut. Comme les autres réponses disent, la valeur 'enrouler autour. c.-à-byte3 = (byte1 + byte2) & 0xFF;

Les bits de début sera tronqué. Il ne nuit pas à une autre mémoire, il est seulement nuisible en termes de résultats inattendus.

Le drapeau de transport ... mais se prépare d'ailleurs le résultat de ne pas être ce que vous attendez, il devrait y avoir aucun effet néfaste.

En général (et le comportement exact dépendra de la langue et de la plate-forme), le résultat sera pris modulo-256. à-dire 150 + 199 = 349. 349 mod 256 = 93.

Cela ne devrait pas affecter tout autre stockage.

Puisque vous avez marqué votre question C #, C ++ et C, je vais répondre à propos de C et C ++. Dans c ++ débordement sur les types signés, y compris sbyte (qui, je crois, est signed char en C / C ++) se traduit par un comportement non défini. Toutefois, pour les types non signés, tels que byte (qui est unsigned char en C ++) est le résultat prend modulo 2 n où n est le nombre de bits dans le type non signé. En C # la deuxième règle est, et les types signés génèrent une exception si elles sont dans le bloc checked. Je peux me tromper dans la partie C #.

Overflow est inoffensif dans c # - vous ne débordera pas la mémoire - vous obtenez simplement obly les 8 derniers bits du résultat. Si vous voulez que cela présente une exception, utilisez le mot-clé « checked ». Notez également que vous pouvez trouver octet + octet donne int, vous devrez peut-être précipité sur octet.

Le comportement dépend de la langue.

En C et C ++, le débordement est signé et non signé dépassement non défini a le comportement que vous avez mentionné (bien qu'il n'y ait pas de type de byte).

En C #, vous pouvez utiliser le mot-clé checked dire explicitement que vous voulez recevoir une exception en cas de débordement et le mot-clé unchecked dire explicitement que vous voulez ignorer.

bit de tête juste déposé.

Et dépassement arithmétique se produit. Depuis 150 + 199 = 349, 1 binaire 0101 1101, on laisse tomber le 1 bit supérieur et l'octet devient 0101 1101; à-dire le nombre de bits d'un octet peut contenir débordé.

Aucun dommage n'a été fait - par exemple mémoire n'a pas trop-plein à un autre endroit.

Regardons ce qui se passe réellement (en C (en supposant que vous avez le type de données approprié, comme certains l'ont fait observer que le C n'a pas un "octet" type de données;néanmoins, il y a 8 bits type de données qui peut être ajouté)).Si ces octets sont déclarées sur la pile, elles existent dans la mémoire principale;à un certain point, les octets copiés sur le processeur pour le fonctionnement (je suis à sauter sur plusieurs mesures importantes, telles que processsor cacher...).Une fois dans le processeur, ils seront stockés dans des registres;le processeur d'exécuter une opération d'ajout sur ces deux registres pour ajouter les données ensemble. C'est ici où la cause de la confusion se produit. Le CPU doit effectuer l'opération d'ajout dans le native (ou parfois, spécifiée) type de données.Disons que le type natif de la CPU est un mot de 32 bits (et que ce type de données est ce qui est utilisé pour l'opération d'ajout);cela signifie que ces octets seront stockées en 32 bits des mots avec la partie supérieure 24 bits unset;l'opération d'ajout sera en effet de faire le dépassement de la cible de mot de 32 bits.Mais (et c'est ici l'important bits) lorsque les données sont copiées à partir du registre de la pile, seule la plus faible de 8 bits (octets) sera recopié à la variable cible de l'emplacement sur la pile.(À noter qu'il y a une certaine complexité avec l'octet de l'emballage et de la pile ici.)

Donc, voici le résultat;les ajouter provoque un dépassement de capacité (selon l'instruction du processeur choisi);cependant, les données est copié du processeur en un type de données de la taille appropriée, de sorte que le dépassement est invisible (et inoffensif, en supposant un écrit correctement le compilateur).

En ce qui concerne C # va, en ajoutant deux valeurs de type byte ensemble se traduit par une valeur de type int qui doit alors être rejetterait à byte.

Par conséquent, votre exemple de code entraînera une erreur du compilateur sans retour coulé à l'octet comme dans ce qui suit.

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

byte byte3 = (byte)(byte1 + byte2);

Voir MSDN pour plus de détails sur cette . De plus, consultez le C # spécification langage , section 7.3.6 promotions numériques.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top