2011-05-04 49 views
31

escribí el siguiente pequeño programa para imprimir la secuencia de Fibonacci:No se puede convertir implícitamente el tipo 'int' a 'corto'

static void Main(string[] 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(); 

} 

El mensaje de compilación es:

No se puede convertir implícitamente el tipo ' int ' a' corto '. Una conversión explícita existe (¿falta un yeso?)

Dado que todo lo que implica es un Int16 (corto), entonces ¿por qué hay ningún conversiones implícitas pasa? Y más específicamente, ¿por qué falla aquí (y no cuando inicialmente se asigna un int a la variable)?

Una explicación sería muy apreciada.

+0

¿En qué línea está el error? ¿Y por qué estás usando pantalones cortos sin interés? –

+4

@Tom id asume la línea donde tiene el comentario Problema en esta línea – Manatherin

+0

Relacionado: http: //stackoverflow.com/questions/1084668/why-is-the-result-of-a-subtraction-of-an-int16 -parameter-from-an-int16-variable-a – SquidScareMe

Respuesta

64

Microsoft convierte sus variables Int16 en Int32 al hacer la función de agregar.

cambiar los siguientes:

Int16 answer = firstNo + secondNo; 

en ...

Int16 answer = (Int16)(firstNo + secondNo); 
+0

Confuso, ¿por qué está diseñado así? ¿Esto causa problemas al agregar dos 'Int64' juntos (y no caben en el espacio de' Int32')? –

+0

Múltiples razones, algunas otras respuestas apuntan a publicaciones que explican * por qué *. –

2

El operador de suma convierte a int operandos primero y luego hace la adición. Entonces el resultado es el int. Debe volver a utilizar el término explícitamente porque las conversiones de tipo "más largo" a "más corto" escriben explícitamente, de modo que no pierda datos accidentalmente con un lanzamiento implícito.

En cuanto a por qué int16 se convierte a int, la respuesta es, porque esto es lo que se define en C# spec. Y C# es de esta manera porque fue diseñado para coincidir estrechamente con la forma en que funciona CLR, y CLR solo tiene una aritmética de 32/64 bits y no de 16 bits. Otros idiomas encima de CLR pueden elegir exponer esto de manera diferente.

4

Al agregar dos valores Int16 se obtiene un valor de Int32. Tendrá que echarlo a Int16:

Int16 answer = (Int16) (firstNo + secondNo); 

Puede evitar este problema cambiando todos sus números a Int32.

1

La línea

Int16 answer = firstNo + secondNo; 

se interpreta como

Int16 answer = (Int32) (firstNo + secondNo); 

Simplemente porque no hay tal cosa como Int16 aritmética.

La solución simple: Do no usar Int16. Use Int32 o simplemente int.

int es su tipo de entero por defecto. corto y largo solo se usan en casos especiales.respuestas

1

El resultado de la suma de dos variables es una Int16Int32:

Int16 i1 = 1; 
Int16 i2 = 2; 
var result = i1 + i2; 
Console.WriteLine(result.GetType().Name); 

Emite Int32.

+0

OK ............. – Aliostad

3

El problema es, que la adición de dos Int16 da como resultado un Int32 como ya se ha señalado.
su segunda pregunta, ¿por qué este problema aún no se producen en la historia de las dos variables se explica aquí: http://msdn.microsoft.com/en-us/library/ybs77ex4%28v=VS.71%29.aspx:

short x = 32767; 

En la declaración anterior, el literal entero 32767 se convierte implícitamente de int a corto. Si el literal entero no cabe en una ubicación de almacenamiento corta, se producirá un error de compilación.

Por lo tanto, la razón por la que funciona en su declaración es simplemente que los literales proporcionados son conocidos por encajar en un short.

0

Por alguna extraña razón, puede usar el operador + = para agregar cortos.

short answer = 0; 
short firstNo = 1; 
short secondNo = 2; 

answer += firstNo; 
answer += secondNo; 
Cuestiones relacionadas