我可以将long转换为int吗?


Answers:


218

做吧(int)myLongValue。它会在unchecked上下文(这是编译器的默认设置)中完全满足您的要求(丢弃MSB并获取LSB )。如果该值不适合,它将OverflowExceptionchecked上下文中抛出int

int myIntValue = unchecked((int)myLongValue);

15
对于任何其他有相同问题的人,我都做过:请注意,丢弃MSB可能会对结果的征兆产生影响。有了以上所述,myIntValuemyLongValue为正数(4294967294 => -2)时,最终可能为负数,反之亦然(-4294967296 => 0)。因此,当实施CompareTo,例如,操作,您无法愉快地将一个减去long另一个的结果转换为an int并将其返回;对于某些值,您的比较将得出错误的结果。
TJ Crowder

21
@Chris:在引擎盖下new Random()使用Environment.TickCount;无需使用时钟滴答进行手动播种。
梅赫达德·阿夫沙里

@MehrdadAfshari一直都是这种情况吗?
克里斯·马里西奇

3
即使这是几年前,我之所以在新的Random中使用它的原因是,我在单元测试中获得了相同的准确结果,并且我想要方差。使用数字给了我差异。
克里斯·马里西奇

3
默认上下文是unchecked,因此,除非您已显式更改它,否则unchecked不需要关键字(如此答案和@ChrisMarisic的注释等所示),并且该关键字int myIntValue = (int)myLongValue完全相同。但是请注意,无论是否使用unchecked关键字,都将得到@TJCrowder描述的非数学粗鲁的截断行为,在某些溢出情况下,符号可能会翻转。真正确保数学正确性的唯一方法是使用checked(...)上下文,这些情况将引发异常。
Glenn Slayden '17

35
Convert.ToInt32(myValue);

虽然我不知道当它大于int.MaxValue时会做什么。


42
“尽管我不知道当它大于int.MaxValue时会做什么”。它将抛出一个OverflowException,这正是OP所不希望的:msdn.microsoft.com/zh-cn/library/d4haekc4.aspx
TJ Crowder

4
如果运行myValue> Integer.Max时需要执行其他处理,请在运行转换之前测试myValue> Integer.Max。否则,Convert.ToInt32(myValue)将溢出(我认为也不例外)。此方法在VB.NET中也适用。
TamusJRoyce 2011年

3
尽管(int)有效,但Convert是一个更好的答案。拥有怪异的异常比怪异的数据更好。
理查德

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 2014年

1
补充一下@Caramiriel所说的话:如果在您当前的应用会话期间用作临时哈希码,则GetHashCode是一个适当的选择。如果您使用的是持久校验和 -稍后运行应用程序时该值将相同,则不要使用GetHashCode,因为不能保证永远是相同的算法。
ToolmakerSteve

9

安全和最快的方法是在投射前使用位掩码。

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

位掩码(0xFFFFFFFF)值将取决于Int的大小,因为Int的大小取决于计算机。


需要确定结果溢出或变为负数时要发生的情况。您显示的内容仍会溢出,IIRC,因为您正在让标志通过。[如另一个答案中所述,在unchecked上下文中您不会溢出-但您无需屏蔽unchecked即可避免溢出,因此仅在checked上下文中才需要解决方案。] 16位示例。有符号16位保留(-32768,32767)。使用0xFFFF进行屏蔽可允许最大65535的值,从而导致溢出IIRC。如果只想为正,则可以屏蔽以避免符号位0x7FFF或0x7FFFFFFF。
ToolmakerSteve

1

它可以通过转换

Convert.ToInt32方法

但是,如果该值超出Int32 Type的范围,它将抛出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)

从数学上讲是正确的方法吗?


如果原始值太大,则会将钳位longValue到最接近的可表示形式int。但是,它对负输入缺乏相同的处理方式,因为它们会丢失最高有效位。您还需要比较Int32.MinValue。不过,原始海报似乎并不想夹紧。
Jeppe Stig Nielsen

恕我直言,有时比获取错误值更容易获得异常,而Int32.MaxValue将是...
G. Goncharov

0

如果值超出Integer范围,则以下解决方案将截断为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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.