2016-11-15 11 views
1

現在、私はC#コードに少し問題があります。 "x^y^z ..."という形式の文字列を数値に変換するコードセットがあるので、このようなメソッドを設定しました。非常に長いロングタイプ番号が負になる

public long valueOfPower() 
{ 
    long[] number = Array.ConvertAll(this.power.Split('^'), long.Parse); 
    if(number.Length == 1) 
    { 
     return number[0]; 
    } 
    long result = number[0]; 
    long power = number[number.Length-1]; 
    for (long i = number.Length-1; i > 1; i--) 
    { 
     power = (long)Math.Pow((int)number[(int)i-1], (int)power); 
    } 
    result= (long)Math.Pow((int)result,(int)power); 
    return result; 
} 

私が抱えている問題は、2^2^2^2^2のようなものが入力されたときに、非常に大きな負の数値が得られることです。 2^2^2^2^2は長いオブジェクトの数値が大きすぎますが、何が起こっているのか分かりません。

"this.power"が2^2^2^2^2の場合、コードが大きな負の数を返すのはなぜですか?しかし、2^2^2^2)? (ランダムなキャストについては申し訳ありませんが、別の番号のタイプを試してみました)

答えて

5

何が起こっているかはオーバーフローです。各データ型は特定のビット数として格納されます。そのビット数は限られているため、データ型に格納できる最大の数は限られています。最上位ビットは数値の符号を表すことが多いため、データ型の最大値を超えると、そのビットは反転し、コンピュータはこれを負の数として解釈します。

数値がオーバーフローする場合は、checkedキーワードを使用して例外をスローすることができます。その詳細はこちらhttps://msdn.microsoft.com/en-us/library/74b4xzyw.aspx

もう1つの解決策はBigIntegerです。詳細:https://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx

C#でのデータ型の最大値のためにこれを参照してください。http://timtrott.co.uk/data-types-ranges/

はオーバーフローに関する詳しい情報は、これを参照してください:https://en.wikipedia.org/wiki/Integer_overflow

+1

私はプロジェクトの 'Property'ページを開いて' Build'に行き、 'Advanced'(右下)をクリックし、' Check for arithmetic overflow /アンダーフロー。すべての設定でこれを行うようにしてください。 –

+0

@BernhardHiller良いヒント。私は実際にそれについて知りませんでした – nhouser9

0

2^2^2^2^2は、まあ、あるquite a large numberその結果であります長いデータ型(9,223,372,036,854,775,807)の最大長をオーバーフローしますが、いくらかのマージンです。

BigIntegerクラスをSystem.Numericsから外してみるか、そのような番号を表す他の方法が考えられます。

0

ダウンキャストを行っているために発生しているオーバーフローの問題があります。

数とパワーlongのはずが、あなたの計算では、EX用されています

power = (long)Math.Pow((int)number[(int)i-1], (int)power); 
// you are downcasting number and power into int. 

あなたはintで計算を行うときには、あなたの価値があるため、オーバーフローのマイナスとなり、その後、あなたはそれを変換longに戻ってください。

また、Math.Powは、パラメータとしてdoubleを受け入れ、doubleを返します。 intをどのようにパラメータとして提供することが許可されているか分かりません。

だから、あなたの問題を解決するために、それは次のようになります。あなたはlongよりも大きな何かを取得したい場合

power = (long)Math.Pow((double)number[(int)i-1], (double)power); 
// and 
result= (long)Math.Pow((double)result,(double)power); 

その後、BigIntegerを使用することを検討してください。

関連する問題