2010-02-14 16 views
3

Considérez cetteint ou uint ou ce

 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 la suite

  • (1) comment pourrait-int maintenir la valeur -2147483646? (Plage int = -2147483648 à 2147483647)
  • (2) pourquoi est-ce -2147483648 d'impression 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é pour cela)

var n = i + 1; à

var n = i + 3;

Edit2: une chose, si comme trop-plein, pourquoi une exception ne ressuscitent pas?

Addition: que le débordement se produit, est-il pas droit de fixer à un autre type en conséquence le type de

var n

dans la déclaration var n = i + 3;?


Nous vous invitons à proposer un meilleur titre, car cela ne fait pas de sens pour moi .... au moins

Merci

+0

pour quoi voter? –

Répondre

6

Mise à jour: Poster fixe sa question.

1) Cette sortie est attendue car vous avez ajouté 3 à int.MaxValue provoquant un débordement. Dans .NET par défaut, il s'agit d'une opération légale dans un code non coché donnant un retour aux valeurs négatives, mais si vous ajoutez un bloc checked autour du code, il lancera un OverflowException à la place.

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

3) Il n'est pas converti en un autre type.

1
  1. This is an overflow, 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 qu'ils sont équivalents. Net.
3
1) -2147483646 is bigger than -2,147,483,648 
2) 2147483648 is out of range 
3) int is an alias for Int32 
3

1)
Tout d'abord, la valeur de la variable n'est pas -2147483646, il est -2147483648. Relancez votre test et vérifiez le résultat.

Il n'y a aucune raison qu'un int ne puisse pas contenir la valeur -2147483646. C'est dans la gamme -2147483648..2147483647.

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

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

3)
Il n'est converti nulle part.

+0

+1 pour être le premier à prendre en compte toute la chose 'var', ce qui je pense était le vrai problème de l'OP. 'var' ne veut pas dire" déterminer quel type est le plus approprié à utiliser ici ". Cela signifie littéralement: «Je suis trop paresseux pour déterminer quel type est votre contribution, alors faites-le pour moi». Cela ne signifie pas que l'utilisation de 'var' est mauvaise, mais vous devez comprendre ce que cela fait si vous voulez l'utiliser correctement. –

1

Ceci est dû à la représentation binaire

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

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

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

lorsque vous essayez le 129e, 1000 0001, les bits de signe get réglée, l'ordinateur pense son -1 au lieu

0

Les opérations arithmétiques dans .NET ne modifient pas le type réel.
Vous commencez avec un entier (32bit) et le +3 ne va pas changer cela.

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 que lors des opérations d'attribution ou comme l'explique Mark lorsque vous définissez les conditions de génération de l'exception.

0

Vous pourriez nous faciliter la tâche en utilisant la notation hexadécimale.

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

Juste sayin'

0

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

abc = checked(i+3) 

à la place. Cela va vérifier les débordements. De plus, en C#, le paramètre par défaut est de ne pas lancer d'exceptions sur les débordements. Mais vous pouvez changer cette option quelque part sur les propriétés de votre projet.