Двойное деление на ноль возвращает ошибку деления на ноль

Я столкнулся с неожиданным поведением и надеялся, что кто-нибудь может помочь с некоторыми рекомендациями относительно того, на каких областях следует сосредоточить расследование.

У меня есть два метода, один по существу выполняет тест деления на ноль на двойном, второй вызывает метод extern для неуправляемой dll.

Примечание. В среде выполнения .Net деление числа Double на ноль должно возвращать значение Infinity (как ни странно, положительное или отрицательное).

Псевдокод того, что я делаю, выглядит примерно так:

InfinityTest(); // Returns an Infinity value as expected
DllCall();
InfinityTest(); // Divide by zero error on second call.

Первый вызов InfinityTest() возвращает значение Infinity, как и ожидалось. Второй вызов InfinityTest() выдает исключение «Делить на ноль», которого я не ожидал.

Обновить

Действующий код InfinityTest() ниже. Для краткости я удалил элементы try/catch и т. д. У меня нет разрешения вдаваться в подробности об элементе псевдокода DllCall(), извините.

private double InfinityTest()
{
    double a = 1.0;
    int b = 0;
    return a / b;
}

person Kynth    schedule 19.04.2011    source источник
comment
Ой! Похоже, что вызов DLL изменяет некоторые флаги FP и не возвращает их обратно. :(   -  person Gabe    schedule 19.04.2011
comment
придет только если пытались разделить число на ноль, число на ноль делить нельзя   -  person Nighil    schedule 19.04.2011
comment
мы могли бы получить код для обоих методов? Что еще более важно, infinityTest();   -  person joe_coolish    schedule 19.04.2011
comment
Можете ли вы опубликовать код внутри InfinityTest();? Можете ли вы рассказать нам, что делает DllCall? Есть ли какая-либо ссылка на DllCall?   -  person Cos Callis    schedule 19.04.2011
comment
закомментируйте DllCall - он по-прежнему выдает исключение?   -  person Steven A. Lowe    schedule 19.04.2011
comment
DLL случайно не написана на Delphi? Я столкнулся с той же проблемой много лет назад, когда работал над интерпретатором VBScript. VBScript предполагает, что ошибки с плавающей запятой незаметно устанавливают биты ошибки на микросхеме FP; Delphi предполагает, что ошибки с плавающей запятой вызывают исключения и меняют поведение чипа в соответствии с ожиданиями.   -  person Eric Lippert    schedule 19.04.2011
comment
@Nighil - Обычно да, и если бы это было int, я был бы счастлив, однако среда выполнения .Net предоставляет значение Infinity, когда Double делится на ноль. Или, по крайней мере, должен :)   -  person Kynth    schedule 20.04.2011
comment
@joe_coolish и @Cos Callis - вскоре я обновлю вопрос с кодом.   -  person Kynth    schedule 20.04.2011
comment
@Eric Lippert - Интересно, я проверю.   -  person Kynth    schedule 20.04.2011
comment
Нет, это определенно как-то связано со звонком. Я обновлю вопрос, чтобы сделать его более понятным, спасибо.   -  person Kynth    schedule 20.04.2011
comment
@Eric Lippert Боюсь, я так и не узнал, в чем для вас была написана сторонняя dll, но я добавил комментарий к ответу Гейба, чтобы уточнить некоторые подробности, подтверждающие, в чем была проблема.   -  person Kynth    schedule 02.09.2011
comment
Я столкнулся с этой проблемой на днях, я изменил QueryPerformanceCounter на QueryThreadCycleTime в своем профилировщике .NET и начал получать странные исключения DivideByZero в профилированном приложении.   -  person leppie    schedule 02.09.2011
comment
Такие комментарии от Nighil — вот почему для комментариев должна быть кнопка «против».   -  person Jim Balter    schedule 06.10.2014


Ответы (1)


Поскольку похоже, что ваша DLL изменяет слово состояния FP на вас, ваш единственный выбор может состоять в том, чтобы изменить его обратно. Я бы предложил P/Invoke для _clearfp или _fpreset. Вот их подписи P/Invoke:

    [DllImport("msvcrt.dll")]
    static extern UInt32 _clearfp();
    [DllImport("msvcrt.dll")]
    static extern void _fpreset();

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

person Gabe    schedule 19.04.2011
comment
На данный момент это решает проблему, пока мы изучаем, почему и как dll изменяет флаги с плавающей запятой, большое спасибо! - person Kynth; 20.04.2011
comment
Третья сторона подтвердила, что их dll действительно изменяет слово состояния FP. После проверки в их конце было обнаружено, что в этом нет необходимости, и dll была обновлена ​​​​для работы без изменения слова состояния FP. Спасибо за вашу помощь. - person Kynth; 02.09.2011