【发布时间】:2015-03-25 02:32:29
【问题描述】:
这真的很奇怪。我正在追踪这个错误:
取反二进制补码的最小值无效。
...原来是因为这样的代码:
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。我相信有人会在语言规范中指出这一点。
标签: c# .net casting .net-4.0 double