Question

Considérez ceci

        int i = 2147483647;
        var n = i + 3;
        i = n;

        Console.WriteLine(i);           // prints -2147483646    (1)
        Console.WriteLine(n);           // prints -2147483646    (2)
        Console.WriteLine(n.GetType()); // prints System.Int32   (3)

Je suis confondu avec suivant

  
      
  • (1) comment pourrait contenir la valeur int -2147483646? (Int range = -2147483648 à 2147483647)
  •   
  • (2) pourquoi est-ce l'impression -2147483648 mais pas 2.147.483.648 (compilateur devrait   mieux décider type que gamme int   dépasse)
  •   
  • (3) si elle est convertie quelque part, pourquoi n.GetType () donne System.Int32   ?
  •   

Edit1: Fait la correction: Maintenant, vous obtiendrez ce que je veux. (Désolé)

  

var n = i + 1; à

     

var n = i + 3;

Edit2: Une chose, si comme trop-plein, pourquoi une exception ne se pose pas

?

Addition: que le débordement se produit, est-il pas le droit de définir le type de

  

var n

dans la déclaration var n = i + 3; à un autre type en conséquence?


vous êtes invités à proposer un meilleur titre, car cela ne fait pas de sens pour moi .... au moins

Merci

Était-ce utile?

La solution

Mise à jour :. Poster fixe sa question

1) Ceci est la sortie est prévu parce que vous avez ajouté 3 à Int.MaxValue provoquant un débordement. Dans .NET par défaut, c'est une opération juridique dans le code décochée donnant une enveloppe autour des valeurs négatives, mais si vous ajoutez un bloc checked autour du code, il lancera une OverflowException à la place.

2) Le type d'une variable déclarée avec var est déterminée au moment de la compilation pas l'exécution. Il est une règle que l'ajout de deux INT32 donne un Int32, pas un UInt32, un Int64 ou autre chose. Ainsi, même si lors de l'exécution, vous pouvez voir que le résultat est trop grand pour un Int32, il doit encore retourner un Int32.

3) Il est pas converti en un autre type.

Autres conseils

 1)  -2147483646 is bigger than -2,147,483,648
 2) 2147483648 is out of range
 3) int is an alias for Int32

1)
Tout d'abord, la valeur de la variable n'est pas -2147483646, il est -2147483648. Exécutez à nouveau votre test et vérifier le résultat.

Il n'y a aucune raison qu'un int ne pouvait pas tenir la valeur -2147483646. Il est dans la plage -2147483648..2147483647.

2)
Le compilateur choisit le type de données de la variable à être le type du résultat de l'expression. L'expression renvoie une valeur int, et même si le compilateur choisirait un plus grand type de données pour la variable, l'expression retourne toujours un entier et vous obtenez la même valeur que résultat.

Il est l'opération dans l'expression qui déborde, ce n'est pas lorsque le résultat est affecté à la variable qu'elle déborde.

3)
Il est pas converti partout.

  1. Ceci est un de trop-plein, votre numéro enroulé autour et est allé négatif
  2. Ce n'est pas le travail du compilateur, comme une boucle à l'exécution peut provoquer la même chose
  3. int est un alias ou System.Int32 ils sont équivalents en .Net.

Ceci est dû à la représentation binaire

vous utilisez Int32, mais la même chose pour char (8 bits)

le premier bit maintient le signe, les bits suivants détiennent le nombre

avec 7 bits, vous pouvez représenter 128 numéros 0111 1111

lorsque vous essayez le 129e, 1000 0001, les bits de signe se définir si l'ordinateur pense que son -1 place

opérations arithmiques .NET ne changent pas le type réel.
Vous commencez avec un (32 bits) entier et 3 ne va pas changer.

C'est aussi la raison pour laquelle vous obtenez un nombre rond inattendu lorsque vous faites ceci:

int a = 2147483647;
double b = a / 4;

ou

int a = 2147483647;
var b = a / 4;

pour cette question.

EDIT :
Il ne fait pas exception, car .NET déborde le nombre.
L'exception de débordement ne se produira à des opérations d'affectation ou Mark explique lorsque vous définissez les conditions pour générer l'exception.

Vous pouvez vous faciliter la tâche à nous tous en utilisant la notation hexagonale.

Tout le monde sait que le huitième premier de Mersenne est 0x7FFFFFFF

Juste sayin'

Si vous voulez une exception à être jeté, écrire

abc = checked(i+3)

au lieu. Cela va vérifier des trop-pleins.

En outre, en c #, le réglage par défaut est de ne pas lancer des exceptions sur les débordements. Mais vous pouvez changer cette option quelque part sur les propriétés de votre projet.

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