2009-07-05 5 views
9

Possible en double:
byte + byte = int… why?Pourquoi le résultat d'une soustraction d'un paramètre Int16 d'une variable Int16 est-il un Int32?

J'ai une méthode comme ceci:

void Method(short parameter) 
{ 
    short localVariable = 0; 
    var result = localVariable - parameter; 
} 

Pourquoi est le résultat d'un Int32 au lieu d'un Int16?

+0

BTW: quel est l'article indéfini correct? "un" ou "un"? –

+0

L'addition et la soustraction de deux valeurs de n'importe quel type T peuvent donner un résultat qui ne rentre pas dans le type T. Voir aussi cette question: http://stackoverflow.com/questions/927391/why-is-a-cast-required -for-byte-soustraction-in-c – schnaader

+2

C'est exactement la même chose que http://stackoverflow.com/questions/941584, juste avec des types différents et un opérateur différent. –

Répondre

11

Il ne s'agit pas simplement de soustraction, il n'existe simplement aucune arithmétique courte (ou octet/sbyte).

short a = 2, b = 3; 
short c = a + b; 

Donner l'erreur de ne pas convertir int (a + b) en court (c).

Une raison de plus pour ne jamais utiliser court.

Supplémentaire: dans tout calcul, short et sbyte seront toujours 'élargis' à int, ushort et byte to uint. Ce comportement remonte à K & R C (et est probablement même plus ancien que cela). La (ancienne) raison de ceci était, afaik, des problèmes d'efficacité et de débordement quand il s'agissait de carboniser. Cette dernière raison ne tient plus si fort pour C#, où un char est 16 bits et non implicitement convertible en int. Mais il est très heureux que les expressions numériques C# restent très compatibles avec C et C++.

+1

Il convient de noter que cela fait partie de la norme C#/CLI. – user7116

1

Je pense que fait fait automatiquement pour éviter tout débordement,

permet de dire que vous faites quelque chose comme ça.

Short result = Short.MaxValue + Short.MaxValue; 

Le résultat ne correspondrait manifestement pas à un résultat court.

une chose que je ne comprends pas est alors pourquoi ne pas le faire pour int32 trop qui convertirait automatiquement à long ???

+0

Ce n'est pas fait pour empêcher le débordement, plus pour décourager le code inefficace. Et c'est hérité de C/C++ –

7

Toutes les opérations avec des nombres entiers inférieurs à Int32 sont élargies à 32 bits avant le calcul par défaut. La raison pour laquelle le résultat est Int32 est simplement de le laisser tel quel après le calcul. Si vous vérifiez les opcodes arithmétiques MSIL, le seul type numérique intégral avec lequel ils opèrent est Int32 et Int64. C'est "par conception".

Si vous souhaitez que le résultat revienne au format Int16, cela n'a pas d'importance si vous exécutez le cast dans le code, ou si le compilateur (hypotétiquement) émet la conversion "sous le capot".

En outre, l'exemple ci-dessus peut être facilement résolu avec les acteurs

short a = 2, b = 3; 

short c = (short) (a + b); 

Les deux numéros se développeraient à 32 bits, se soustrait, puis tronquée revenir à 16 bits, ce qui est de la SP destinée à être .

L'avantage d'utiliser à court (ou octet) est principalement le stockage dans les cas où vous avez des quantités massives de données (données graphiques, streaming, etc.)

post-scriptum Oh, et l'article est "a" pour les mots dont la prononciation commence avec une consonne, et "an" pour les mots dont la forme prononcée commence par une voyelle. Un nombre, AN int.;)

+3

+1 Bonne réponse. (Et mérite un bonus pour votre réponse sur l'article indéfini. ;-)) –

+1

Excellent, Kek444. Vous devriez ajouter votre réponse à cette question connexe (http://stackoverflow.com/questions/941584/byte-byte-int-why). Je le mettrais définitivement en cause. –

+1

Merci pour les commentaires positifs, fera l'affaire. –

3

Les autres réponses dans ce fil, ainsi que les discussions donnés ici sont instructifs:

(1) Why is a cast required for byte subtraction in C#?

(2) byte + byte = int… why?

(3) Why is a cast required for byte subtraction in C#?

Mais juste pour y jeter une autre ride, cela peut dépendre des opérateurs que vous utilisez. Les opérateurs d'incrémentation (++) et de décrémentation (-) ainsi que les opérateurs d'affectation d'addition (+ =) et d'assignation de soustraction (- =) sont surchargés pour une variété de types numériques et effectuent l'étape supplémentaire de conversion du résultat retour au type de l'opérande lors du retour du résultat.

Par exemple, en utilisant court:

short s = 0; 

s++;    // <-- Ok 
s += 1;    // <-- Ok 
s = s + 1;   // <-- Compile time error! 
s = s + s;   // <-- Compile time error! 

l'octet:

byte b = 0; 

b++;    // <-- Ok 
b += 1;    // <-- Ok 
b = b + 1;   // <-- Compile time error! 
b = b + b;   // <-- Compile time error! 

Si elles ne le font pas de cette façon, les appels à l'aide l'opérateur d'incrémentation (++) serait impossible et les appels à l'opérateur d'affectation d'addition serait maladroit au mieux, par exemple:

short s 
s += (short)1; 

Quoi qu'il en soit, juste une autre que Pect à cette discussion ...

1

L'effet que vous voyez ...

short - short = int 

... est discuté longuement dans cette question Stackoverflow: [link] byte + byte = int… why?

Il y a beaucoup de bonne information et certains discussions intéressantes pour expliquer pourquoi c'est comme ça.

est ici le "top voté" réponse:

Je crois qu'il est fondamentalement pour le bien de la performance. (En termes de "pourquoi il se produit du tout" c'est parce qu'il n'y a pas d'opérateurs définis par C# pour arithmétique avec octet, sbyte, court ou ushort, comme d'autres l'ont dit. les opérateurs ne sont pas définis.)

processeurs ont des activités indigènes à faire de l'arithmétique avec 32 bits très rapidement. Faire la conversion retour à partir du résultat à un octet automatiquement pourrait être fait, mais serait entraîner des pénalités de performance dans le cas où vous ne voulez pas vraiment ce comportement.

- Jon Skeets

Profitez,

Robert C.Cartaino

Questions connexes