Это действительно странно. Я выследить эту ошибку:Различное поведение литья
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
Какого черта здесь происходит? Почему оценка этих, казалось бы, идентичных выражений дает такие разные результаты?
Update:
Найдено подсказку. Шестигранное представление 4.70259123E14
и -1141206336
является:
0x42FABB2BBFA92C00
0xBBFA92C0
Так что я думаю, один из слепков пихают биты непосредственно в int
. Итак, -2147483648
- большая тайна.
Интересно. Кажется, разница между проверенным и непроверенным поведением.Использование высокотехнологичного приложения «Калькулятор» (конечно, в режиме «Программист» ;-) Я вижу, что '-1141206336' соответствует усеченному (32 lsb)' 470259123000000'. Проверенная версия возвращает return 'int.MinValue'. Я уверен, что кто-то сможет указать это на языке спецификации. – Alex