Как я вынуждаю компилятор C# выдать исключение, когда какая-либо математическая операция производит 'NaN'?

Некоторые математические функции в программе, которую я недавно записал, возвращают недопустимые значения, такие как NaN (возможно из-за не проверки входных параметрических усилителей некоторой функции). Проблема состоит в том, что довольно трудно разыскать, какие функции передают неправильные значения. Это приводит к ошибкам, распространяемым всюду по коду и заставляющим программу разрушить минуты или несколько часов спустя, если вообще.

Интересно, существует ли способ поймать эти дефектные операции момент, значение NaN следует из любой операции (в значительной степени то же как в 'исключении DivisionByZero', выданном некоторыми компиляторами C/C++, если я помню).

Заранее спасибо.

P.D: не стесняйтесь повторно отмечать мой вопрос в случае необходимости.

5
задан Trap 12 February 2010 в 12:03
поделиться

4 ответа

Если вы не увидите ваш код, этот ответ будет непременно расплывчатым, но один из способов сделать это - проверить вывод вашей функции и проверить, "NaN" "поднять и исключить:

if (double.IsNaN(result))
{
    throw new ArithmeticException();
}

Но с более подробной информацией об исключении.

ОБНОВЛЕНИЕ

Чтобы перехватить возникновение определенного исключения, вы можете (временно) прервать выполнение, когда исключение выбрасывается в отладчике.

Выберите Отладка> Исключения , затем разверните дерево, чтобы выбрать Исключения среды CLR> Система> System.ArithmeticException, и установите флажок «Выброшено».

Проблема в том, что он будет ломаться везде, где он будет брошен, а не только в вашем коде. Размещение явного кода на достаточно низком уровне позволяет обойти это.

9
ответ дан 18 December 2019 в 06:11
поделиться

Я не знаю, работает ли это в среде CLR, но вы можете использовать _controlfp_s from для запуска исключений с плавающей запятой:

unsigned int _oldState;
errno_t err = _controlfp_s(&oldState, 0, MCW_EM);
assert(!err);

Для сброса:

errno_t err = _controlfp_s(0, _oldState, MCW_EM);
assert(!err);
5
ответ дан 18 December 2019 в 06:11
поделиться

Проекты, зависящие друг от друга, не означают, что параллелизация невозможна. Системы сборки достаточно умны, чтобы понять и избежать критических депендаций. Иначе gcc не сможет использовать 4 ядра.

Поэтому (в дополнение к другим шагам), почему бы просто не попробовать включить многопроцессорную обработку в Visual Studio с помощью/MP (см. http://msdn.microsoft.com/en-us/library/bb385193.aspx ).

-121--1066995-

Вы возвращаете адрес локальной переменной, которая больше не существует при выходе функции потока. В любом случае, зачем звонить pthread_exit? почему бы просто не вернуть значение из функции потока?

void *myThread()
{
   return (void *) 42;
}

и затем в основном:

printf("%d\n",(int)status);   

Если нужно вернуть сложное значение такой структуры, то, вероятно, проще всего динамически распределить его через malloc () и вернуть указатель. Конечно, код, инициировавший поток, будет отвечать за освобождение памяти.

-121--1127674-

Вы имеете в виду, что ищете какую-либо настройку или опцию, чтобы как только любой int получит присвоенное значение NaN , вы хотели бы создать исключение? Я уверен, что такого не существует. Существует опция галочки , которая предупреждает вас о переполнении, но это не то же самое.

Я думаю, что единственной альтернативой отладке вручную является изменение кода так, как предложил ChrisF. Всегда можно установить #, если DEBUG вокруг броска, чтобы остановить выброс производственного кода.

3
ответ дан 18 December 2019 в 06:11
поделиться

Вы всегда можете попробовать условный разрыв в режиме отладки, ниже приводится ссылка на полный ответ, поскольку я ответил кому-то еще с аналогичным вопросом:

Условная отладка

Это позволит вам просто приостановить выполнение, когда условия встретились, возможно, это не исключение, но, тем не менее, оно должно вам помочь.

0
ответ дан 18 December 2019 в 06:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: