MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Исключение деления на ноль C#"
Answer 1019768
Никак, потому что исключения нет. Деление на ноль для double вместо исключения выдает специальное значение (Infinity или NaN):
Arithmetic operations with the float and double types never throw an exception. The result of arithmetic operations with those types can be one of special values that represent infinity and not-a-number
double a = 1.0 / 0.0; Console.WriteLine(a); // output: Infinity Console.WriteLine(double.IsInfinity(a)); // output: True Console.WriteLine(double.MaxValue + double.MaxValue); // output: Infinity double b = 0.0 / 0.0; Console.WriteLine(b); // output: NaN Console.WriteLine(double.IsNaN(b)); // output: True
Но для отлова деления на ноль в общем случае это использовать нельзя, так как эти же значения могут говорить о переполнении или, скажем, о конвертации в double непредставимого в нем битового значения. Так что только проверка делителя перед делением.
Конкретно для Windows на архитектурах x86/x86-64 можно включить аппаратное исключение при делении на ноль с помощью _controlfp_s:
using System; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { /* msvcrt.dll - недокументированная версия Microsoft CRT, поставляемая с Windows. Можно вместо нее взять CRT из конкретной версии Visual C++ Redistributable, например msvcr110.dll для Visual C++ 2012 */ [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] static extern uint _controlfp_s(ref uint _CurrentState, uint _NewValue, uint _Mask); const uint _EM_ZERODIVIDE = 0x00000008; const uint _MCW_EM = 0x0008001f; static bool EnableFloatingPointTrap() { uint control_word = 0; uint err = _controlfp_s(ref control_word, 0, 0); if (err != 0) return false; //снимаем флаг, маскирующий исключение при делении на ноль uint control_word_new = control_word & ~_EM_ZERODIVIDE; err = _controlfp_s(ref control_word, control_word_new, _MCW_EM); if (err != 0) return false; return true; } static void Main(string[] args) { EnableFloatingPointTrap(); double x = 0.0; double y = 1.0 / x; //System.DivideByZeroException Console.WriteLine(y); Console.ReadKey(); } } }
Однако делать так не рекомендуется, так как неизвестно, как поведет себя CLR, если поменять флаги процессора на неожиданные для нее значения. Кроме того, другой код может вернуть назад значение флага.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.