[comp.windows.ms.programmer] Windows and Floating Point

ebergman@isis.cs.du.edu (Eric Bergman-Terrell) (06/03/91)

I'm working on a Windows program that does a lot of floating point 
calculations.  I'm using BC++ 2.0 on my 386SX which does have a 387SX
math coprocessor.

The Problem:  If I leave the program running and shell out to DOS and then
come back, the Windows program usually crashes, sometimes with a UAE, and
sometimes with a message like "coprocessor stack underflow".

What's even stranger is that I didn't do any floating point while in DOS-land.

So I tried the following:  in my main event loop (switch statement from HELL)
I call a routine to reset the 8x87 upon receipt of WM_KILLFOCUS and
WM_SETFOCUS messages.  The routine is just:

asm fwait
asm finit
asm fwait

Result:  I haven't been able to make the problem recur.  Even if I shell out
to DOS in the middle of a computation, the program doesn't crash when I get
back.

SO:  is Windows forgetting to save/restore the coprocessor state when the
DOS shell is started?  Or is this the responsibility of the programmer?
Furthermore, is it safe to simply call the finit instruction?  I'm assuming
that on a machine lacking a math chip the instruction will cause the 
corresponding emulation routine to be called.  I'll find out tomorrow when
I try the prog. on a coprocessorless machine...

Furthermore, is the Windows floating point emulation library documented 
ANYWHERE?  I have Petzold, Prog. Ref., Guide to Programming, and the DOCS
for BC++ 2.0.  Haven't found any coverage of the emul library anywhere
...


Terrell

dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (06/03/91)

In article <1991Jun3.045252.5431@mnemosyne.cs.du.edu> ebergman@isis.cs.du.edu (Eric Bergman-Terrell) writes:
>The Problem:  If I leave the program running and shell out to DOS and then
>come back, the Windows program usually crashes, sometimes with a UAE, and
>sometimes with a message like "coprocessor stack underflow".
>
>What's even stranger is that I didn't do any floating point while in DOS-land.
>
>So I tried the following:  in my main event loop (switch statement from HELL)
>I call a routine to reset the 8x87 upon receipt of WM_KILLFOCUS and
>WM_SETFOCUS messages.  The routine is just:
>
>asm fwait
>asm finit
>asm fwait
>
>Result:  I haven't been able to make the problem recur.  Even if I shell out
>to DOS in the middle of a computation, the program doesn't crash when I get
>back.

This fix is a little dangerous.  After the FINIT, the 387 will be configured
to mask all errors:  it won't report problems like stack underflow, it'll just
return NaN as a result.  You should take frequent looks at the status word
to see if any exceptions have occurred if you do this, but watch out:
at least in Turbo Pascal, the sticky bits in the status word aren't sticky. 
The floating point string conversion routines reset them.  BC++ may have the
same bug.

Duncan Murdoch