フィボナッチ数列を出力するために、次の小さなプログラムを作成しました。
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();
}
コンパイルメッセージは次のとおりです。
型 'int'を 'short'に暗黙的に変換することはできません。明示的な変換が存在します(キャストを見逃していますか?)
関連するものはすべてInt16(short)であるため、暗黙の変換が行われているのはなぜですか?そして、より具体的には、なぜここで失敗するのですか(変数に最初にintを割り当てるときではありません)?
説明をいただければ幸いです。
MicrosoftはInt16
変数からInt32
追加機能を実行するとき。
以下を変更します。
Int16 answer = firstNo + secondNo;
に...
Int16 answer = (Int16)(firstNo + secondNo);
これらの質問に対するEric Lippertの回答を読む
問題は、2つのInt16
を追加すると、他の人が既に指摘したようにInt32
になるということです。
2番目の質問、これらの2つの変数の宣言でこの問題が発生しない理由については、こちらで説明します。 http://msdn.Microsoft.com/en-us/library/ybs77ex4% 28v = VS.71%29.aspx :
short x = 32767;
上記の宣言では、整数リテラル32767は暗黙的にintからshortに変換されます。整数リテラルが短い保存場所に収まらない場合、コンパイルエラーが発生します。
したがって、宣言で機能する理由は、提供されたリテラルがshort
に収まることがわかっているからです。
何らかの奇妙な理由で、+ =演算子を使用してショートを追加できます。
short answer = 0;
short firstNo = 1;
short secondNo = 2;
answer += firstNo;
answer += secondNo;
プラス演算子は、まずオペランドをintに変換してから加算を行います。結果はintです。 「長い」型から「短い」型への変換は明示的に行われるため、暗黙的にキャストして誤ってデータを失うことはないため、明示的にshortにキャストする必要があります。
なぜint16がintにキャストされるのかという答えは、これが C#spec で定義されているからです。 C#がこのようになっているのは、CLRが動作する方法に密接に一致するように設計されており、CLRには16ビットではなく32/64ビットの算術演算しかないためです。 CLRの他の言語では、これを異なる方法で公開することを選択する場合があります。
この線
Int16 answer = firstNo + secondNo;
と解釈されます
Int16 answer = (Int32) (firstNo + secondNo);
Int16算術演算などは存在しないためです。
簡単な解決策:Do Int16を使用しない。 Int32または単にint
を使用します。
int
はデフォルトの整数型です。 shortとlongは、特別な場合にのみ使用されます。
2つのInt16
変数を合計した結果はInt32
です:
Int16 i1 = 1;
Int16 i2 = 2;
var result = i1 + i2;
Console.WriteLine(result.GetType().Name);
Int32
を出力します。
これは、2つのInt16
を追加した結果がInt32
であるためです。ここで「変換」の段落を確認してください。 http://msdn.Microsoft.com/en-us/library/ybs77ex4%28v=vs.71%29.aspx