J’ai écrit le petit programme suivant pour imprimer la séquence de Fibonacci:
static void Main(ssortingng[] args) { Console.Write("Please give a value for n:"); Int16 n = Int16.Parse(Console.ReadLine()); Int16 firstNo = 0; Int16 secondNo = 1; Console.WriteLine(firstNo); Console.WriteLine(secondNo); for (Int16 i = 0; i < n; i++) { //Problem on this line Int16 answer = firstNo + secondNo; Console.WriteLine(answer); firstNo = secondNo; secondNo = answer; } Console.ReadLine(); }
Le message de compilation est:
Impossible de convertir implicitement le type ‘int‘ en ‘short’. Une conversion explicite existe (manque-t-il un casting?)
Puisque tout ce qui est impliqué est un Int16 (court), alors pourquoi y a-t-il des conversions implicites en cours? Et plus précisément pourquoi l’échec ici (et non lors de l’atsortingbution initiale d’un int à la variable)?
Une explication serait très appréciée.
Microsoft convertit vos variables Int16
en Int32
lorsque vous Int32
la fonction d’ajout.
Changer ce qui suit:
Int16 answer = firstNo + secondNo;
dans…
Int16 answer = (Int16)(firstNo + secondNo);
Lire les réponses d’ Eric Lippert à ces questions
L’ajout de deux valeurs Int16
donne une valeur Int32
. Vous devrez le lancer en Int16
:
Int16 answer = (Int16) (firstNo + secondNo);
Vous pouvez éviter ce problème en basculant tous vos numéros sur Int32
.
Le problème est que l’ajout de deux résultats Int16
donne un résultat Int32
comme d’autres l’ont déjà souligné.
Votre deuxième question, pourquoi ce problème ne se produit pas déjà lors de la déclaration de ces deux variables, est expliquée ici: http://msdn.microsoft.com/en-us/library/ybs77ex4%28v=VS.71%29.aspx :
short x = 32767;
Dans la déclaration précédente, le littéral entier 32767 est implicitement converti de int en short. Si le littéral entier ne rentre pas dans un emplacement de stockage court, une erreur de compilation se produira.
Ainsi, la raison pour laquelle cela fonctionne dans votre déclaration est simplement que les littéraux fournis sont connus pour tenir dans un short
.
L’opérateur plus convertit les opérandes en int d’abord, puis effectue l’addition. Donc, le résultat est l’int. Vous devez le redéfinir explicitement parce que les conversions d’un type “plus long” vers un type “plus court” sont rendues explicites, de sorte que vous ne perdiez pas accidentellement des données avec une diffusion implicite.
Quant à savoir pourquoi int16 est converti en int, la réponse est: car c’est ce qui est défini dans la spécification C # . Et C #, c’est parce qu’il a été conçu pour correspondre exactement à la façon dont fonctionne le CLR, qui n’a qu’une arithmétique de 32/64 bits et non de 16 bits. D’autres langues en plus de CLR peuvent choisir d’exposer cela différemment.
Le résultat de la sum de deux variables Int16
est un Int32
:
Int16 i1 = 1; Int16 i2 = 2; var result = i1 + i2; Console.WriteLine(result.GetType().Name);
Il génère Int32
.
La ligne
Int16 answer = firstNo + secondNo;
est interprété comme
Int16 answer = (Int32) (firstNo + secondNo);
Tout simplement parce qu’il n’existe pas d’arithmétique Int16.
La solution simple: ne pas utiliser Int16 . Utilisez Int32 ou simplement int
.
int
est votre type entier par défaut. court et long ne sont utilisés que dans des cas particuliers.
Pour une raison étrange, vous pouvez utiliser l’opérateur + = pour append des courts métrages.
short answer = 0; short firstNo = 1; short secondNo = 2; answer += firstNo; answer += secondNo;
C’est parce que le résultat de l’ajout de deux Int16
est un Int32
. Consultez le paragraphe “conversions” ici: http://msdn.microsoft.com/en-us/library/ybs77ex4%28v=vs.71%29.aspx