17

I am experiencing an unexpected behaviour and was hoping someone could help with some guidance as to what areas to focus an investigation on.

I have two methods, one essentially performs a divide by zero test on a double, the second calls an extern method for an unmanaged dll.

Note: In the .Net runtime, dividing a Double by Zero should return an Infinity value (amusingly of either positive or negative flavours).

Pseudocode for what I am doing looks something like this:

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

The first call to InfinityTest() returns the value Infinity as expected. The second call to InfinityTest() throws a Divide by Zero exception that I didn't expect.

Update

The effective InfinityTest() code below. For brevity I've removed try/catch elements, etc. I do not have permission to go into details about the DllCall() pseudocode element, apologies.

private double InfinityTest()
{
    double a = 1.0;
    int b = 0;
    return a / b;
}
Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
Kynth
  • 2,597
  • 1
  • 18
  • 24
  • 7
    Ouch! It looks like the DLL call changes some FP flags and doesn't put them back. :( – Gabe Apr 19 '11 at 16:36
  • it will come only if tried to divide a number by zero, a number cannot be divided by zero – Nighil Apr 19 '11 at 16:36
  • 3
    could we get the code for both methods? More importantly the `infinityTest();` – joe_coolish Apr 19 '11 at 16:37
  • 3
    Can you post the code from inside the "InfinityTest();"? Can you tell us what the DllCall does? Are there any reference passed to the DllCall? – Cos Callis Apr 19 '11 at 16:37
  • 2
    Is the DLL by any chance written in Delphi? I ran into the same problem many years ago when I was working on the VBScript interpreter. VBScript assumes that floating point errors silently set error bits on the FP chip; Delphi assumes that floating point errors cause exceptions and will reset the behaviour of the chip to meet its expectations. – Eric Lippert Apr 19 '11 at 18:47
  • @Nighil - Normally yes, and if this was an int I'd be happy, however the .Net runtime supplies a value of Infinity when a Double is divided by zero. Or, at least, it should :) – Kynth Apr 20 '11 at 08:15
  • @joe_coolish and @Cos Callis - I'll update the question with some code shortly. – Kynth Apr 20 '11 at 08:15
  • @Eric Lippert - Interesting, I'll check. – Kynth Apr 20 '11 at 08:17
  • @Eric Lippert I never found out what the third party dll was written in for you I'm afraid, but I have added a comment to Gabe's answer to follow up with some more details confirming what the problem was. – Kynth Sep 02 '11 at 09:45
  • 1
    I ran into this issue the other day, I changed from `QueryPerformanceCounter` to `QueryThreadCycleTime` in my .NET profiler and started getting weird DivideByZero exceptions in profiled app. – leppie Sep 02 '11 at 09:52
  • comment out the DllCall - does it still throw the exception? – Steven A. Lowe Apr 19 '11 at 16:39
  • No, it's certainly something to do with the call. I'll update the question to make it clearer, thanks. – Kynth Apr 20 '11 at 08:18
  • Comments like that by Nighil is why there should be a downvote button for comments. – Jim Balter Oct 06 '14 at 19:02

1 Answers1

13

Since it sounds like your DLL is changing the FP status word on you, your only choice may be to change it back. I would suggest P/Invoke to _clearfp or _fpreset. Here are their P/Invoke signatures:

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

This may not reset things back to exactly the way they were, but hopefully it will be close enough.

Gabe
  • 84,912
  • 12
  • 139
  • 238
  • This is working around the issue fine for now while we look into why/how the dll is altering the floating point flags, thank you very much! – Kynth Apr 20 '11 at 09:59
  • 1
    The third party has confirmed that their dll was indeed changing the FP status word. After a review at their end this was found to not be needed and the dll has been updated to work without the FP status word change. Thanks for your help. – Kynth Sep 02 '11 at 09:43