2013-07-26 4 views
-1

я получаю странные ошибки на этом маленьком фрагменте кода:OverflowException на вычислении разности DateTime

private int CalculateDifference(DateTime date1, DateTime date2) 
{ 
    var difference = date1 - date2; 
    return Math.Abs((int)difference.TotalSeconds); 
} 

В моем случае я вычисление разности 3520789176.4909997 полных секунд. Программа генерирует исключение, я никогда не видел в течение десяти лет C# кодирования:

System.OverflowException: "Negating the minimum value of a twos complement number is invalid."

I'm довольно уверен, подмигнул, связанные с плавающей точкой арифметики, но я не понимаю, детали и мне просто нужно достаточное решение для определения разницы двух значений даты.

+1

Прочтите это http://stackoverflow.com/questions/6265381/c-sharp-short-error-negating-the-minimum-value-of-a-twos-complement-number-is-i –

+0

Вы почти уверен в том, что это ложь. –

+0

Int32.MaxValue секунд составляет менее 70 лет. – Corak

ответ

6

Проблема заключается в том, что, когда двойной превышает диапазон значений, которые могут быть выражены в int — который является -2,147,483,648 к 2,147,483,647, результат не определен в соответствии с C# спецификации (см Jeppe Stig Nielsen's comment ниже), но в .NET, является int.MinValue. Таким образом, при преобразовании difference к int, она принимает значение, -2147483648, которые затем не могут быть сведены на нет с помощью Math.Abs

Если преобразовать этот метод использовать long вместо этого, он должен работать:

private long CalculateDifference(DateTime date1, DateTime date2) 
{ 
    var difference = date1 - date2; 
    return Math.Abs((long)difference.TotalSeconds); 
} 

Вы могли также решить эту проблему, просто преобразование в int после того как вы приняли абсолютное значение:

private int CalculateDifference(DateTime date1, DateTime date2) 
{ 
    var difference = date1 - date2; 
    return (int)Math.Abs(difference.TotalSeconds); 
} 
+0

Вы: _it берет самое близкое значение, -2,147,483,648_ Нет, в этом конкретном случае требуется *** самое дальнее *** значение. Возможно (не совсем точно), что «Int32.MinValue» создается во всех «невозможных» случаях. C# Spec говорит: (следующий комментарий) –

+0

«В контексте« unchecked »преобразование всегда выполняется успешно и выполняется следующим образом: Если значение операнда NaN или бесконечное, результатом преобразования является неопределенное значение тип назначения. В противном случае операнд источника округляется до нуля до ближайшего интегрального значения. Если это целочисленное значение находится в пределах диапазона назначения, то это значение является результатом преобразования. В противном случае результат преобразования является неопределенным значением типа назначения. " –

+0

Другим решением будет 'difference.Duration(). Ticks/TimeSpan.TicksPerSecond' (и все равно должен возвращать' long'). Выглядит более неуклюжий, но избегает преобразования целого числа в число с плавающей запятой и обратно в целое число. –

0

Согласно msdn: значение Int.Maxvalue равно 2 147 483 647

Ваш номер, кажется, больше этого.

Смежные вопросы