这真的很奇怪。我跟踪这个错误:不同的铸造行为
Negating the minimum value of a twos complement number is invalid.
...和事实证明,这是由于这样的代码:
var valueFromUser = "470259123000000";
var doubleValue = Convert.ToDouble(valueFromUser, CultureInfo.InvariantCulture);
Math.Abs((int)doubleValue);
事实上,当我在LINQPad运行此:
(int)Convert.ToDouble("470259123000000", CultureInfo.InvariantCulture)
...它给了我:
-2147483648
然而,另一名开发人员在这里说,他得到完全不同的东西(而不是在LINQPad):
-1141206336
当我试图通过自身的恒定,以评估只是演员:
(int)470259123000000.0
...我由于需要unchecked
而出现编译错误。而这个:
unchecked((int)470259123000000.0)
...评估为-1141206336
像其他开发者得到。所以我想也许Convert
创造了一个微妙的不同于常数的值。不,这个计算结果为True
:
Convert.ToDouble("470259123000000", CultureInfo.InvariantCulture) == 470259123000000.0
到底是什么怎么回事?为什么评估这些看起来相同的表达式会产生不同的结果?
更新:
找到一个提示。的4.70259123E14
和-1141206336
十六进制表示是:
0x42FABB2BBFA92C00
0xBBFA92C0
所以我想了铸件一种是直接推搡位到int
。所以-2147483648
是更大的谜。
有趣。看起来像检查和未检查铸件行为之间的区别。使用高科技的“计算器”应用程序(当然在“程序员”模式;-)我可以看到'-1141206336'匹配'470259123000000'的截尾(32 lsb)。选中的版本似乎返回'int.MinValue'。我相信有人能够在语言规范中指出这一点。 – Alex 2015-03-25 03:02:39