2010-06-20 15 views
21

Si tengo dos byte s a y b, ¿cómo es que:¿Por qué los operadores binarios de C# siempre devuelven int independientemente del formato de sus entradas?

byte c = a & b; 

produce un error de compilación acerca de bytes de fundición a int? Hace esto incluso si puse un molde explícito delante de a y b.

Además, sé de this question, pero realmente no sé cómo se aplica aquí. Parece que se trata del tipo de devolución de operator &(byte operand, byte operand2), que el compilador debería poder resolver como cualquier otro operador.

+1

Consulte http://stackoverflow.com/questions/1214629 o http://stackoverflow.com/questions/927391 o http://stackoverflow.com/questions/941584 y es posible que tenga su respuesta ... – Joey

+0

posible duplicado de [byte + byte = int ... ¿por qué?] (http://stackoverflow.com/questions/941584/byte-byte-int-why) – nawfal

Respuesta

22

¿Por qué los operadores bit a bit de C# siempre devuelven int independientemente del formato de sus entradas?

No estoy de acuerdo con always. Esto funciona y el resultado de a & b es de tipo long:

long a = 0xffffffffffff; 
long b = 0xffffffffffff; 
long x = a & b; 

El tipo de retorno no es int si uno o ambos de los argumentos son long, ulong o uint.


¿Por qué los operadores bit a bit de retorno int C# 's si sus entradas son bytes?

El resultado de byte & byte es un int porque no hay & operador definido en bytes. (Source)

Existe un operador & para int y también hay una conversión implícita de byte a int por lo que cuando se escribe byte1 & byte2 esto es efectivamente lo mismo que escribir ((int)byte1) & ((int)byte2) y el resultado de esto es un int.

+0

Es cierto, pero eso no explica por qué el resultado es ** En t**. –

+0

@Philippe Leybaert: Se agregó un párrafo adicional. –

+1

¿eh? explica exactamente e inequívocamente por qué el resultado es int. – fearofawhackplanet

2

Es porque & se define en enteros, no en bytes, y el compilador arroja implícitamente sus dos argumentos a int.

5

Los operadores binarios no están definidos para los tipos de bytes (entre otros). De hecho, todos (numéricos) operadores binarios actúan única en los siguientes tipos nativos:

  • int
  • uint
  • largo
  • ulong
  • flotador
  • doble
  • decimal

Si hay otros tipos involucrados, utilizará uno de los anteriores.

It's all in the C# specs version 5.0 (Section 7.3.6.2):

promoción numérica binaria se produce para los operandos de la predefinido +, -, *, /,%, &, |, ^, ==, =,>, <,! > = y < = operadores binarios. La promoción numérica binaria convierte implícitamente ambos operandos a un tipo común que, en el caso de los operadores no relacionales, también se convierte en el tipo de resultado de la operación. promoción numérica binaria consiste en aplicar las reglas siguientes, en el orden en que aparecen aquí:

  • Si alguno de los operandos es de tipo decimal, el otro operando se convierte al tipo decimal o se produce un error en tiempo de compilación si el otro operando es de tipo flotante o doble.
  • De lo contrario, si cualquiera de los dos operandos es de tipo double, el otro operando se convierte a tipo double.
  • De lo contrario, si cualquiera de los dos operandos es de tipo float, el otro operando se convierte en tipo float.
  • De lo contrario, si cualquiera de los dos operandos es de tipo ulong, el otro operando se convierte en tipo ulong, o se produce un error en tiempo de compilación si el otro operando es de tipo sbyte, corto, int o largo.
  • De lo contrario, si cualquiera de los dos operandos es de tipo largo, el otro operando se convierte en tipo largo.
  • De lo contrario, si el operando es de tipo uint y el otro operando es de tipo sbyte, short o int, ambos operandos se convierten a tipo long.
  • De lo contrario, si cualquiera de los operandos es de tipo uint, el otro operando se convierte a tipo uint.
  • De lo contrario, ambos operandos se convierten a tipo int.
+1

Básicamente, es porque los diseñadores de C# determinaron que el costo era demasiado alto para escribir una regla separada para los operadores bit a bit (que no pueden desbordar) de la de los operadores aritméticos (que puede). Es trivial mostrar que tener el compilador insertando un molde implícito es seguro, porque el valor está siempre en el rango del tipo más estrecho. Pero aparentemente los costos de especificar, escribir y probar ese comportamiento se consideraron mayores que el beneficio. –

+0

En realidad, no tiene nada que ver con operadores bit a bit o no. Simplemente no hay operadores que actúen en tipos de bytes. –

+0

+1 para enlace a las especificaciones. –

12

Este comportamiento es una consecuencia del diseño de IL, el lenguaje intermedio generado por todos los compiladores .NET. Si bien admite los tipos enteros cortos (byte, sbyte, short, ushort), solo tiene un número muy limitado de operaciones. Cargar, almacenar, convertir, crear matriz, eso es todo. Esto no es un accidente, ese es el tipo de operaciones que podría ejecutar eficientemente en un procesador de 32 bits, cuando se diseñó IL y RISC era el futuro.

La comparación binaria y las operaciones de sucursal solo funcionan en int32, int64, int nativo, punto flotante nativo, objeto y referencia administrada. Estos operandos son de 32 bits o 64 bits en cualquier núcleo de CPU actual, lo que garantiza que el compilador JIT pueda generar código de máquina eficiente.

Usted puede leer más sobre esto en la ECMA 335, la partición I, capítulo 12.1 y partición III, capítulo 1,5


escribí un más extenso post sobre esto over here.

Cuestiones relacionadas