469,127 Members | 1,341 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,127 developers. It's quick & easy.

Catching floating point errors

Hi,

I have a very large Visual c++ .net 2003 7.1 native c application
(approximately 500,000 lines of code). This application is a simulation
that frequently works with floating point numbers.

From time to time I do something bad -- for example divide by zero or try
to grow a float beyond numeric_limits<float>::max()

I told MSVC .net 2003 7.1 to "Break into the debugger" for ALL exceptions in
the "Exceptions" dialog. In particular, there is a red circle/x in all the
floating point related exceptions under "Win32 Exceptions" indicating the
debugger should break when it encounters such an exception.

Believe it or not, despite all my hard work making little red Xs, the
debugger does not always stop execution when I perform a funny float
operation.

My question: how do I have MSVC 7.1 .net 2003 break on funny floating point
errors?

PS: Each of my threads execute this code when they start up:
_control87(_EM_INVALID | _EM_DENORMAL |_EM_ZERODIVIDE | _EM_OVERFLOW |
_EM_UNDERFLOW | _EM_INEXACT, _MCW_EM);
Thanks,

Chris
Nov 17 '05 #1
13 4888
"Chris Stankevitz" <ch******@stankevitz.nospamplease.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Believe it or not, despite all my hard work making little red Xs, the
debugger does not always stop execution when I perform a funny float
operation.

My question: how do I have MSVC 7.1 .net 2003 break on funny floating
point errors?


It may be that the runtime is masking the exceptions. Take a look at this

http://msdn.microsoft.com/library/de..._controlfp.asp

and if it does not help, post again.

Regards,
Will
Nov 17 '05 #2
> It may be that the runtime is masking the exceptions. Take a look at this

and if it does not help, post again.

Will,

That did not help. I used control87 to tell the runtime to catch floating
point exceptions, but it still let one slip through.

Here's a screenshot of MSVC .net 7.1 2003 letting a sqrt of negative number
slip through:
http://www.stankevitz.com/visualstudio/stat.png

And here's a screenshot of me calling control87 just a few steps back on the
call stack:
http://www.stankevitz.com/visualstudio/control87.png

And here's a screenshot of my exception settings:
http://www.stankevitz.com/visualstudio/exceptions.png
FYI, this is the control87 line I used:
_control87(_EM_INVALID | _EM_DENORMAL |_EM_ZERODIVIDE | _EM_OVERFLOW |
_EM_UNDERFLOW | _EM_INEXACT, _MCW_EM);
Thanks for your assistance!

Chris
Nov 17 '05 #3
I believe, the code does not throw. The reason is that the floating point
numbers have infinity and undefined values, which precludes undefined
results of operations.
My question: how do I have MSVC 7.1 .net 2003 break on funny floating point errors?
You better check them manually.

--
Vladimir Nesterovsky
e-mail: vl******@nesterovsky-bros.com
home: www.nesterovsky-bros.com
I have a very large Visual c++ .net 2003 7.1 native c application
(approximately 500,000 lines of code). This application is a simulation
that frequently works with floating point numbers.

From time to time I do something bad -- for example divide by zero or try
to grow a float beyond numeric_limits<float>::max()

I told MSVC .net 2003 7.1 to "Break into the debugger" for ALL exceptions in the "Exceptions" dialog. In particular, there is a red circle/x in all the floating point related exceptions under "Win32 Exceptions" indicating the
debugger should break when it encounters such an exception.

Believe it or not, despite all my hard work making little red Xs, the
debugger does not always stop execution when I perform a funny float
operation.

My question: how do I have MSVC 7.1 .net 2003 break on funny floating point errors?

Nov 17 '05 #4
"Chris Stankevitz" <ch******@stankevitz.nospamplease.com> wrote in message
news:uZ**************@TK2MSFTNGP15.phx.gbl...
FYI, this is the control87 line I used:
_control87(_EM_INVALID | _EM_DENORMAL |_EM_ZERODIVIDE | _EM_OVERFLOW |
_EM_UNDERFLOW | _EM_INEXACT, _MCW_EM);


I haven't had the "pleasure" of doing floating point calcualtions since the
'80s when mortgage backed securities were the rage so I had to read the help
for _control87() twice. <g>

Nevertheless, I just tried this in VS.Net 2003,

float f;
unsigned int u;

u = _controlfp(0, 0);
u = u & ~(_EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW |
_EM_UNDERFLOW | _EM_INEXACT);

_controlfp(u, _MCW_EM);

f = 1 / f;
f = sqrt(-1.0f);

The last two lines raise exceptions in the debugger.

Regards,
Will
Nov 17 '05 #5

"William DePalo [MVP VC++]" <wi***********@mvps.org> wrote in message
news:OV**************@TK2MSFTNGP10.phx.gbl...
Nevertheless, I just tried this in VS.Net 2003,


Will,

Thanks for your help.

Do these "control87" commands need to be issued on every thread in the app?
Do I need to constantly apply them to guarantee they "stick"? Can other
processes disable them? Can opening a common dialog (such as File | Open)
reset them?

Thanks,

Chris
Nov 17 '05 #6
"William DePalo [MVP VC++]" <wi***********@mvps.org> wrote in message
news:OV**************@TK2MSFTNGP10.phx.gbl...
The last two lines raise exceptions in the debugger.

Ahh... I solved the problem. I had the bits inverted in the first argument
to the _control87 function.

This raised a second problem (pun not intended). When an invalid floating
point operation occurs and is caught by correct use of _control87, the call
stack gets hosed. I cannot see where the exception happened in my code!

It appears the floating point error jumps the code into the kernel and blows
the call stack. :(

Anyone know how I can track down these floating point errors?

Thanks again for your help,

Chris
Nov 17 '05 #7

"Vladimir Nesterovsky" <vl******@nesterovsky-bros.com> wrote in message
news:eX**************@TK2MSFTNGP09.phx.gbl...
I believe, the code does not throw.


Hi Vladimir,

Thanks for your help. I suspect that *some* code causes FP exceptions to
throw or else they wouldn't have placed FP exceptions in this dialog:

http://www.stankevitz.com/visualstudio/exceptions.png

Thanks,

Chris
Nov 17 '05 #8
> It appears the floating point error jumps the code into the kernel and
blows the call stack. :(

This example illustrates the point. Create a console app and set exceptions
as shown here:
http://www.stankevitz.com/visualstudio/exceptions.png

Then compile/run this code:
//--------------------

#include <cfloat>
#include <cmath>

int main()
{
_control87(0, _MCW_EM);

sqrt(-1.0);

return 0;
}

//--------------------

Thanks,

Chris
Nov 17 '05 #9
"Chris Stankevitz" <ch******@stankevitz.nospamplease.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Do these "control87" commands need to be issued on every thread in the
app?
As I said, I don't do any "scientific" calculation these days. But as the
exception mechanism of the platform _is thread based_, I think that the
answer is yes.
Do I need to constantly apply them to guarantee they "stick"?
Good question. I don't know. I would guess that the runtime sets the
exception policy while processing the DLL_THREAD_ATTACH notification and not
thereafter. That's a guess. If you have the runtime source (disclaimer: I
can't say for certain how much is distributed with the VS.Net IDE) you might
want to take a look.
Can other processes disable them?
I can't think of an easy way.
Can opening a common dialog (such as File | Open) reset them?


Well, the thing to note about exception handlers under Win32 is that they
are stack-frame based (tabling for now the issue of "vectored" exception
handing). So, if you call on a common dialog and if it does something like
this

__try
{
DoTheCommonDialogThing();
}

__except ( blah blah blah ... )
{
// swallow the exception and move on
}

then you (the caller) will never see it.

Regards,
Will
Nov 17 '05 #10
"Chris Stankevitz" <ch******@stankevitz.nospamplease.com> wrote in message
news:%2******************@TK2MSFTNGP10.phx.gbl...
It appears the floating point error jumps the code into the kernel and
blows the call stack. :(


Turns out the call stack comes back if you "pass exception on the caller" a
few times.

Okay, my problem is solved, thanks for your help everyone!

Chris
Nov 17 '05 #11
"Chris Stankevitz" <ch******@stankevitz.nospamplease.com> wrote in message
news:uq**************@TK2MSFTNGP09.phx.gbl...
This raised a second problem (pun not intended).
:-)
When an invalid floating point operation occurs and is caught by correct
use of _control87, the call stack gets hosed. I cannot see where the
exception happened in my code!


Does your exception handler call _clearfp()? I think that that is required
to clear the exception. I'm wondering whether your problem is that the
exception is signalled mre times than you think because it has not been
cleared.

As I said before in this thread, that's just a guess.

Regards,
Will
Nov 17 '05 #12
Chris Stankevitz wrote:
Turns out the call stack comes back if you "pass exception on the caller" a
few times.

Okay, my problem is solved, thanks for your help everyone!


One more thing to consider is that FPU exceptions are somewhat asynchronous
and may not be raised until a subsequent FPU instruction is executed. You
can raise any pending FPU exceptions with:

__asm { fwait }

I just found an an article on MSDN which mentions this:

Microsoft Visual C++ Floating-Point Optimization
http://msdn.microsoft.com/library/de.../floapoint.asp

I haven't had a chance to read this article, but it looks very good.

--
Doug Harrison
Microsoft MVP - Visual C++
Nov 17 '05 #13
> processes disable them? Can opening a common dialog (such as File | Open)
reset them?


Hi,

just add to previous answers, some device drivers (e.g. HP printer drivers)
mask FPU exceptions and do not restore them back. So it can happen in your
program, that after call to some API (3rd party DLL or so), the exceptions
will be masked. On the contrary, some 3rd party DLL may not work due to
unmasked exceptions. (We unmasked FPU exceptions in AutoCAD 2k, and it won't
even start due to divion by zero)

Jan
Nov 17 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

13 posts views Thread by Dylan Nicholson | last post: by
15 posts views Thread by michael.mcgarry | last post: by
7 posts views Thread by cmay | last post: by
4 posts views Thread by jacob navia | last post: by
8 posts views Thread by Jon Rea | last post: by
4 posts views Thread by John Pye | last post: by
24 posts views Thread by usenet | last post: by
1 post views Thread by CARIGAR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.