【发布时间】:2010-10-25 22:13:38
【问题描述】:
我想将long 转换为int。
如果long的值>int.MaxValue,我很乐意让它环绕。
最好的方法是什么?
【问题讨论】:
标签: c# types int type-conversion long-integer
我想将long 转换为int。
如果long的值>int.MaxValue,我很乐意让它环绕。
最好的方法是什么?
【问题讨论】:
标签: c# types int type-conversion long-integer
只需(int)myLongValue。它会在unchecked 上下文(这是编译器默认值)中完全按照您的意愿(丢弃 MSB 并采用 LSB)。如果值不适合int,它将在checked 上下文中抛出OverflowException:
int myIntValue = unchecked((int)myLongValue);
【讨论】:
myLongValue 为正 (4294967294 => -2) 时,myIntValue 最终可能为负,反之亦然 (-4294967296 => 0)。因此,例如,在实现CompareTo 操作时,您不能愉快地将另一个long 减去一个int 的结果转换为int 并返回它;对于某些值,您的比较会产生不正确的结果。
new Random() 在后台使用Environment.TickCount;无需使用时钟滴答声手动播种。
unchecked,因此除非您明确更改它,否则不需要unchecked 关键字(如本答案和@ChrisMarisic 的评论等所示),并且int myIntValue = (int)myLongValue 完全等价。但是请注意,无论您是否使用unchecked 关键字,您都会得到@T.J.Crowder 描述的非数学粗鲁截断行为,其中符号在某些溢出情况下会翻转。真正确保数学正确性的唯一方法是使用 checked(...) 上下文,这些情况将引发异常。
Convert.ToInt32(myValue);
虽然我不知道当它大于 int.MaxValue 时它会做什么。
【讨论】:
OverflowException,这正是 OP 所没有的'想要:msdn.microsoft.com/en-us/library/d4haekc4.aspx
Convert 不好。
if (value > Int32.MaxValue) return Int32.MaxValue; else return Convert.ToInt32( value );
有时您实际上并不对实际值感兴趣,而是对它作为 checksum/hashcode 的用法感兴趣。在这种情况下,内置方法GetHashCode() 是一个不错的选择:
int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
【讨论】:
GetHashCode 是一个合适的选择。如果您使用持久校验和 - 稍后运行应用程序时将保持相同的值,则不要使用GetHashCode,因为不能保证永远是相同的算法。
安全最快的方法是在施法前使用位掩码...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
位掩码 (0xFFFFFFFF) 值将取决于 Int 的大小,因为 Int 大小取决于机器。
【讨论】:
unchecked 上下文中,您不会出现溢出-但您不需要在unchecked 中进行屏蔽以避免溢出,因此仅在checked 上下文中需要解决方案。] 16 位的示例。有符号的 16 位保持 (-32768, 32767)。使用 0xFFFF 屏蔽允许值高达 65535,从而导致溢出,IIRC。如果只需要正数,可以屏蔽以避免符号位 0x7FFF 或 0x7FFFFFFF。
一种可能的方法是使用取模运算符只让值保持在 int32 范围内,然后将其强制转换为 int。
var intValue= (int)(longValue % Int32.MaxValue);
【讨论】:
(int)(longValue > Int32.MaxValue ? (longValue % Int32.MaxValue) + 1 : longValue)。可以为负值添加类似的逻辑:(int)(longValue < Int32.MinValue ? (longValue % Int32.MaxValue) - 1 ? (longValue > Int32.MaxValue ? (longValue % Int32.MaxValue) + 1 : longValue))
如果值超出整数范围,以下解决方案将截断为 int.MinValue/int.MaxValue。
myLong < int.MinValue ? int.MinValue : (myLong > int.MaxValue ? int.MaxValue : (int)myLong)
【讨论】:
可以转换成
Convert.ToInt32 方法
但是如果值超出 Int32 类型的范围,它会抛出一个溢出异常。 一个基本的测试将向我们展示它是如何工作的:
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.
Here还有更长的解释。
【讨论】:
不会
(int) Math.Min(Int32.MaxValue, longValue)
在数学上是正确的方式吗?
【讨论】:
longValue 钳制 到最近的可表示int。但它缺乏对过负输入的相同处理,反而会丢失最高有效位;您还需要与Int32.MinValue 进行比较。不过,最初的海报似乎不想被夹住。
(int)Math.Max(Int32.MinValue, Math.Min(Int32.MaxValue, longValue))。但是我发现等效的 stackoverflow.com/a/58011064/199364 更容易理解。