longをintに変換できますか?


回答:


218

ただしてください(int)myLongValueuncheckedコンテキストで(MSBを破棄し、LSBを取得して)希望どおりに実行します(これはコンパイラのデフォルトです)。値がに収まらない場合はOverflowExceptioncheckedコンテキスト内でスローされますint

int myIntValue = unchecked((int)myLongValue);

15
同じ質問をした他の人のために:私はMSBを破棄すると結果の符号に影響を与える可能性があることに注意してください。上記の場合、が正()のmyIntValue場合myLongValueは負に4294967294 => -2なり、その逆(-4294967296 => 0)の場合もあります。したがって、CompareToたとえば演算を実装する場合、あるものlongから別のものに減算した結果を喜んでキャストしてintそれを返すことはできません。一部の値については、比較によって誤った結果が生じる可能性があります。
TJクラウダー、

21
@Chris:内部でnew Random()使用Environment.TickCountします。クロックティックを手動でシードする必要はありません。
Mehrdad Afshari、2011年

@MehrdadAfshariは常にそうでしたか?
Chris Marisic、2011年

3
これは数年前のことですが、新しいRandomで使用した理由は、単体テストで同じ正確な結果が得られ、分散が必要だったからです。数値を使用すると、差異が生じました。
Chris Marisic 2015

3
デフォルトのコンテキストはuncheckedなので、明示的に変更しない限り、uncheckedキーワード(この回答や@ChrisMarisicのコメントなどに示されている)は不要であり、int myIntValue = (int)myLongValueまったく同じです。ただし、uncheckedキーワードを使用するかどうかに関係なく、@ TJCrowderで説明されている非数学的な失礼な切り捨て動作が発生し、オーバーフローの場合に符号が反転する可能性があることに注意してください。数学的な正確さを確実に保証する唯一の方法はchecked(...)、それらのケースが例外をスローするコンテキストを使用することです。
Glenn Slayden 2017

35
Convert.ToInt32(myValue);

int.MaxValueより大きい場合はどうなるかわかりませんが。


42
"int.MaxValueより大きい場合はどうなるかわかりませんが"がスローされますがOverflowException、これはまさにOPが望まないものです:msdn.microsoft.com/en-us/library/d4haekc4.aspx
TJクラウダー、

4
myValue> Integer.Maxのときに他の処理を行う必要がある場合は、変換を実行する前にmyValue> Integer.Maxかどうかをテストします。それ以外の場合は、Convert.ToInt32(myValue)がオーバーフローします(例外ではないと思います)。この方法はVB.NETでも機能します。
TamusJRoyce、2011年

3
(int)は有効ですが、Convertの方が適しています。奇妙なデータよりも奇妙な例外を持つ方が良いです。
リチャード6

1
@RichardJuneええと、違う?ここでのOP は、「longの値> int.MaxValueの場合、折り返しさせていただきます」と明確に述べています。一般的に、あなたのステートメントについて議論しているように見えますが、この特定のケースでは、違いますConvert
ruffin

if (value > Int32.MaxValue) return Int32.MaxValue; else return Convert.ToInt32( value );
セルゲイ

15

時には、実際の値に実際に関心がなく、checksum / hashcodeとしての使用法に関心がある場合があります。この場合、組み込みの方法GetHashCode()が適切です。

int checkSumAsInt32 = checkSumAsIn64.GetHashCode();

7
この回答が出されてからしばらく前ですが、ハッシュコードの実装は.NETバージョン間で異なる可能性があることを述べておきます。これは実際には発生していない可能性がありますが、この値が異なるアプリケーション実行/アプリドメイン間で同じである保証はありません。
Caramiriel 14年

1
@Caramirielが言っていることに追加するには:現在のアプリセッション中に一時的なハッシュコードとして使用する場合GetHashCodeは、適切な選択です。あなたが後にしている場合、永続的チェックサム -後であなたのアプリを実行したときと同じになる値は、使用しないでくださいGetHashCode、永遠に同じアルゴリズムであることが保証されていないとして、。
ToolmakerSteve

9

安全かつ最速の方法は、キャスト前にビットマスキングを使用することです...

int MyInt = (int) ( MyLong & 0xFFFFFFFF )

0xFFFFFFFFIntサイズはマシンに依存するため、ビットマスク()値はIntのサイズに依存します。


結果がオーバーフローするか、負の数になる場合に何を実行するかを決定する必要があります。あなたが示すものはまだオーバーフローします、IIRC、あなたはサインを少し通過させているからです。[別の回答で述べたように、uncheckedコンテキストではオーバーフローは発生しませんが、オーバーフローuncheckedを回避するためにマスクする必要がないため、ソリューションはcheckedコンテキストでのみ必要です。] 16ビットの例。符号付き16ビットホールド(-32768、32767)。0xFFFFでマスキングすると、最大65535の値が許容され、オーバーフロー、IIRCが発生します。正のみが必要な場合は、符号ビットを回避するためにマスクすることができます(0x7FFFまたは0x7FFFFFFF)。
ToolmakerSteve 2018

1

変換できます

Convert.ToInt32メソッド

ただし、値がInt32タイプの範囲外の場合、OverflowExceptionがスローされます。基本的なテストでは、それがどのように機能するかを示します。

long[] numbers = { Int64.MinValue, -1, 0, 121, 340, Int64.MaxValue };
int result;
foreach (long number in numbers)
{
   try {
         result = Convert.ToInt32(number);
        Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
                    number.GetType().Name, number,
                    result.GetType().Name, result);
     }
     catch (OverflowException) {
      Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.",
                    number.GetType().Name, number);
     }
}
// The example displays the following output:
//    The Int64 value -9223372036854775808 is outside the range of the Int32 type.
//    Converted the Int64 value -1 to the Int32 value -1.
//    Converted the Int64 value 0 to the Int32 value 0.
//    Converted the Int64 value 121 to the Int32 value 121.
//    Converted the Int64 value 340 to the Int32 value 340.
//    The Int64 value 9223372036854775807 is outside the range of the Int32 type.

ここに長い説明があります。


0

しない

(int) Math.Min(Int32.MaxValue, longValue)

数学的に言えば、正しい方法ですか?


これは、元の値が非常に大きい場合、を最も近い表現可能なものに固定します。しかし、あまりにも負の入力を処理するのと同じ扱いが欠けているため、代わりに最上位ビットが失われます。あなたも比較する必要があります。ただし、元のポスターはクランプを必要としていなかったようです。longValueintInt32.MinValue
Jeppe Stig Nielsen

IMHOは、Int32.MaxValueがそうである間違った値よりも例外を取得する方が良い場合があります...
G.ゴンチャロフ

0

次のソリューションは、値が整数の範囲外の場合、int.MinValue / int.MaxValueに切り捨てます。

myLong < int.MinValue ? int.MinValue : (myLong > int.MaxValue ? int.MaxValue : (int)myLong)

0

可能な方法は、モジュロ演算子を使用して、値をint32の範囲にとどまらせ、それをintにキャストすることです。

var intValue= (int)(longValue % Int32.MaxValue);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.