【问题标题】:Can I convert long to int?我可以将 long 转换为 int 吗?
【发布时间】:2010-10-25 22:13:38
【问题描述】:

我想将long 转换为int

如果long的值>int.MaxValue,我很乐意让它环绕。

最好的方法是什么?

【问题讨论】:

    标签: c# types int type-conversion long-integer


    【解决方案1】:

    只需(int)myLongValue。它会在unchecked 上下文(这是编译器默认值)中完全按照您的意愿(丢弃 MSB 并采用 LSB)。如果值不适合int,它将在checked 上下文中抛出OverflowException

    int myIntValue = unchecked((int)myLongValue);
    

    【讨论】:

    • 对于与我有相同问题的其他人:请注意,丢弃 MSB 可能会对结果的 sign 产生影响。综上所述,myLongValue 为正 (4294967294 => -2) 时,myIntValue 最终可能为负,反之亦然 (-4294967296 => 0)。因此,例如,在实现CompareTo 操作时,您不能愉快地将另一个long 减去一个int 的结果转换为int 并返回它;对于某些值,您的比较会产生不正确的结果。
    • @Chris: new Random() 在后台使用Environment.TickCount;无需使用时钟滴答声手动播种。
    • 默认上下文是unchecked,因此除非您明确更改它,否则不需要unchecked 关键字(如本答案和@ChrisMarisic 的评论等所示),并且int myIntValue = (int)myLongValue 完全等价。但是请注意,无论您是否使用unchecked 关键字,您都会得到@T.J.Crowder 描述的非数学粗鲁截断行为,其中符号在某些溢出情况下会翻转。真正确保数学正确性的唯一方法是使用 checked(...) 上下文,这些情况将引发异常。
    【解决方案2】:
    Convert.ToInt32(myValue);
    

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

    【讨论】:

    • “虽然我不知道当它大于 int.MaxValue 时它会做什么” 它会抛出一个OverflowException,这正是 OP 所没有的'想要:msdn.microsoft.com/en-us/library/d4haekc4.aspx
    • 在运行转换前测试myValue > Integer.Max,如果在myValue > Integer.Max时需要做其他处理。 Convert.ToInt32(myValue) 否则会溢出(我相信也不例外)。此方法也适用于 VB.NET。
    • 虽然 (int) 有效,但 Convert 是更好的答案。奇怪的异常比奇怪的数据更好。
    • @RichardJune 嗯,不是吗?这里的 OP 明确地 说,“如果 long > int.MaxValue 的值,我很乐意让它环绕。”我可以看到总体上争论你的陈述,但在这个特定情况,不,Convert 不好。
    • if (value > Int32.MaxValue) return Int32.MaxValue; else return Convert.ToInt32( value );
    【解决方案3】:

    有时您实际上并不对实际值感兴趣,而是对它作为 checksum/hashcode 的用法感兴趣。在这种情况下,内置方法GetHashCode() 是一个不错的选择:

    int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
    

    【讨论】:

    • 自从给出这个答案已经有一段时间了,尽管我想提一下哈希码实现可能在 .NET 版本之间有所不同。这实际上可能不会发生,但不能保证此值在不同的应用程序运行/应用程序域之间是相同的。
    • 补充@Caramiriel 所说的:如果在您当前的应用会话期间用作临时 哈希码,那么GetHashCode 是一个合适的选择。如果您使用持久校验和 - 稍后运行应用程序时将保持相同的值,则不要使用GetHashCode,因为不能保证永远是相同的算法。
    【解决方案4】:

    安全最快的方法是在施法前使用位掩码...

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

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

    【讨论】:

    • 需要决定当结果溢出或变成负数时你想要发生什么。 IIRC,您显示的内容仍然会溢出,因为您让符号位通过。 [正如另一个答案中提到的,在unchecked 上下文中,您不会出现溢出-但您不需要在unchecked 中进行屏蔽以避免溢出,因此仅在checked 上下文中需要解决方案。] 16 位的示例。有符号的 16 位保持 (-32768, 32767)。使用 0xFFFF 屏蔽允许值高达 65535,从而导致溢出,IIRC。如果只需要正数,可以屏蔽以避免符号位 0x7FFF 或 0x7FFFFFFF。
    【解决方案5】:

    一种可能的方法是使用取模运算符只让值保持在 int32 范围内,然后将其强制转换为 int。

    var intValue= (int)(longValue % Int32.MaxValue);
    

    【讨论】:

    • 这对我来说效果最好,因为所有其他位掩码尝试都将 281474976710656 (2^48) 转换为 0。
    • @GuiRitter - 某些较大的值仍会变为 0。(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))
    【解决方案6】:

    如果值超出整数范围,以下解决方案将截断为 int.MinValue/int.MaxValue。

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

    【讨论】:

      【解决方案7】:

      可以转换成

      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还有更长的解释。

      【讨论】:

        【解决方案8】:

        不会

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

        在数学上是正确的方式吗?

        【讨论】:

        • 如果原始值太大,这会将longValue 钳制 到最近的可表示int。但它缺乏对过负输入的相同处理,反而会丢失最高有效位;您还需要与Int32.MinValue 进行比较。不过,最初的海报似乎不想被夹住。
        • 恕我直言,有时比错误值更好地获得异常,这 Int32.MaxValue 将是......
        • 要限制负值,请执行(int)Math.Max(Int32.MinValue, Math.Min(Int32.MaxValue, longValue))。但是我发现等效的 stackoverflow.com/a/58011064/199364 更容易理解。
        猜你喜欢
        • 1970-01-01
        • 2011-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-21
        • 2014-03-13
        相关资源
        最近更新 更多