【问题标题】:Casting UInt32 to Int32: Different compiler results将 UInt32 转换为 Int32:不同的编译器结果
【发布时间】:2013-08-01 20:18:27
【问题描述】:

我正在阅读How can one simplify network byte-order conversion from a BinaryReader?,问题中的初始代码让我想到了UInt32Int32 之间显式转换的功能。我主要关心的是大于Int32.MaxValue 或小于0 的值。

这些转换应该是等价的,但是一个有效,另一个导致错误:

public static void TestConverstion()
{
    // runs just fine, CastBack == aUInt
    UInt32 aUInt = UInt32.MaxValue; // 4294967295
    Int32 anInt = (Int32)aUInt; // -1
    UInt32 castBack = (UInt32)aUInt; // 4294967295

    // Build Error: Constant value '4294967295' cannot be converted to a 'int' (use 'unchecked' syntax to override) 
    UInt32 oneLineCastBack = (UInt32)(Int32)UInt32.MaxValue;
}

为什么一个有效而另一个无效?

这个演员的行为记录在哪里?我能找到的最好的文档是Explicit Numeric Conversions Table (C# Reference),它承认存在显式转换,但警告显式转换“可能导致精度损失或引发异常”。实验表明不会抛出异常,也不会丢失精度。

UInt32 Structure 建议由于UInt32 不是Common Language Specification 的一部分,因此您应该只使用Int64 并在需要表示高于Int32.MaxValue 但低于UInt32.MaxValue 的值时浪费一半位.

【问题讨论】:

  • 记录在哪里? msdn.microsoft.com/en-us/library/2xf6xbyc.aspxmsdn.microsoft.com/en-us/library/aa288039.aspx。 MSDN 几乎可以回答有关基本内容的任何问题。
  • 很明显,第一个是 variable,所以编译器无法猜测第二个是 Constant 时会发生什么,所以编译器知道范围并将您投诉为错误。跨度>
  • Convert.ToInt32(uint)和(Int32)(uint)的操作一样吗?
  • 但是如果它是有效的运行时操作,为什么编译器会抱怨呢?
  • Convert.ToInt32(uint) 是与 (Int32)(uint) 不同的操作。第一个抛出异常(相当预期),第二个似乎根据值的位表示转换得很好。 (这是 C++ 中的行为,但我更希望 C# 中出现异常)。

标签: c# casting uint explicit-conversion


【解决方案1】:

按照您的代码布局方式,您只是在处理编译器确定潜在结果的能力。没有什么真正改变。正如错误消息向您建议的那样,您可以这样做并得到完全相同的结果:

unchecked { UInt32 oneLineCastBack = (UInt32)(Int32)UInt32.MaxValue; }

您给出的两个示例之间的唯一区别是,第二个示例将const直接转换Int32,编译器可以立即将其识别为错误。 p>

【讨论】:

  • msdn.microsoft.com/en-us/library/a569z7k8(v=vs.71).aspx "如果既不使用checked也不使用unchecked,则常量表达式在编译时使用默认的溢出检查,即被检查。否则,如果表达式为非常数,则运行时溢出检查取决于其他因素,例如编译器选项和环境配置。” - 所以这个值在赋值给一个变量后就变成了一个非常数,描述接下来会发生什么的语言是模糊的。
  • 我和你在一起,这是模糊的。但是正确的是,没有关于有意义的环境和编译器选项的声明?你可以从列表中剔除,但是...msdn.microsoft.com/en-us/library/19z1t1wy.aspx
  • 这可能是正确的编译器选项:msdn.microsoft.com/en-us/library/8wtf2dfz.aspx 它提到了截断的情况,但没有提到相同位数的不同位表示的情况。
猜你喜欢
  • 2020-12-07
  • 2015-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 2017-07-03
  • 1970-01-01
  • 2011-03-02
相关资源
最近更新 更多