[comp.lang.fortran] MS Fortran 5.00 FP underflows

bcphyagi@Twg-S5.uucp (Stephen Walton) (09/21/90)

I am building a fairly large application using MS Fortran 5.00.
For no apparent reason, I am getting message M6111, "floating-point
error: stack underflow" in my code.  Worse, apparently random
changes make the error go away:  things like changing by 1 the
initial guess fed to a nonlinear least squares fitting routine.
(The parameter in question is the center position of a Gaussian
which is several wide in the units I'm using.)

A while back, I complained about this to Microsoft, and they sent
me a new 87.lib for MS Fortran 4.1 and MS C 5.1.  Should I use this
with MS Fortran 5.0 as well?  I really don't feel like debugging
Microsoft's compiler for them.
--
Stephen R. Walton, Dept. of Physics and Astronomy, Cal State Northridge
I am srw@csun.edu no matter WHAT the stupid From: line says!

jb@falstaff.mae.cwru.edu (Jim Berilla) (09/21/90)

In article <1990Sep20.215410.4844@csun.edu> bcphyagi@Twg-S5.uucp (Stephen Walton) writes:
[ He is having a problem with MS Fortran 5.00 floating point ]

Well, sorry I can't help on that particular problem, but I can point out
a few other bugs that cost me days of work.  The compiler generates
incorrect code in the following cases:

1.  Using integer*1 variables in array subscripts.
    This test program illustrates the problem:
	integer*1 a(4,100)
	integer*1 i1,i2
	read (*,*) i1,i2
	a(i1,i2)=1
	end
    The assembly code generated for line 4 shows the subscript is wrong:
	mov	al,$S15_I1	; move value of i1 to al
	cbw			; convert to word.  ok so far.
	mov	bx,ax		; move to index
	mov	al,$S16_I2	; move value of i2 to al
	shl	al,1		; instead of multiplying by 4, shift left
	shl	al,1		;   by 2 bits.  If i2=32, then the result
				;   is a signed -128, not unsigned +128.
	cbw			; converts byte to word, but sign extends.
	mov	si,ax
	mov	BYTE PTR $S14_A[bx-5][si],1
    If you input i1=1 and i2=32 (both legal int*1 values) then the offset
    into the array is -132, before the start of the array.  (or is it +65404?
    in any case, it's wrong.)

2.  Setting an int*1 array to a default of #ff.  May fail on other values.
    Another test program:
	integer*1 a(16),b

	a=#ff			! this doesn't work right.
	write (*,'(16(1xz2))') a

	do i=1,16		! this doesn't work either.
	  a(i)=#ff		! the loop is really only executed 8 times,
	end do			!   it stores a word value each time.
	write (*,'(16(1xz2))') a

	a=-128			! this really screws up.
	write (*,'(16(1xz2))') a

	b=#ff
	a=b			! this one works.
	write (*,'(16(1xz2))') a

	end

    Executing this program, I find that the first 3 methods of initializing
    the array fail:

 FF FE FF FE FF FE FF FE FF FE FF FE FF FE FF FE
 FF FE FF FE FF FE FF FE FF FE FF FE FF FE FF FE
 80 7F 80 7F 80 7F 80 7F 80 7F 80 7F 80 7F 80 7F
 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

    The compiler apparently tries to optimize by storing word values instead
    of byte values when the value is a constant, but doesn't generate the
    right constant.  This occurs even with the /Od switch (Optimization off.)
>
>A while back, I complained about this to Microsoft, and they sent
>me a new 87.lib for MS Fortran 4.1 and MS C 5.1.  Should I use this
>with MS Fortran 5.0 as well?  I really don't feel like debugging
>Microsoft's compiler for them.

I tried to talk to Microsoft.  These problems existed in 4.1, and I called
them about it.  After spending 15 minutes getting routed to someone who
knew what Fortran was, the only response was something like "Gee, we don't
know anything about that."  I gave up.

It's scarey to think that there are bugs like this in a mature product like
Fortran.  Especially when Fortran is used mostly in engineering, where
things like bridges, nuclear reactors, and submarines are designed using
Fortran programs.  Fortunately, I still use my slide rule to check the
answers.  (Actully, I use an HP-15)

-- 
      Jim Berilla / jb@falstaff.cwru.edu / 216-368-6776
"My opinions are my own, except on Wednesday mornings at 9 AM,
           when my opinions are those of my boss."

gill@bnlux0.bnl.gov (ronald gill) (09/22/90)

I tried to email, but it bounced back.  I had a similar FP problem
with a large program using MicroSoft FORTRAN 4.0.  If I added a line
or two the program would crash, even if the line was just i=0, or
something trivial.  I solved it by compiling with the HUGE attribute,
ie.: fl /AH /FPi87 ...  Apparantly, the program was just overflowing
some segment and external routines that were being called got lost.
I was calling some C routines that controlled a tape drive, some VDI
routines for graphics, plotters, etc.  It still has a problem that
when you do an EXIT or STOP, the system crashes!  I solved that by
using a PAUSE instead, and giving the user a message to Control-C to
exit the program: that seems to work.  Talk about a kludge...

--Rongill

tholen@uhccux.uhcc.Hawaii.Edu (David Tholen) (09/22/90)

In article <1990Sep21.082155.1743@usenet.ins.cwru.edu>, jb@falstaff.mae.cwru.edu (Jim Berilla) writes:
 
> 1.  Using integer*1 variables in array subscripts.
>     This test program illustrates the problem:
> 	integer*1 a(4,100)
> 	integer*1 i1,i2
> 	read (*,*) i1,i2
> 	a(i1,i2)=1
> 	end

Hmm.  Interesting.  An INTEGER*1 variable can have only 256 discrete values,
which in this case is certainly adequate for each dimension of the array, but
the array is stored linearly in memory, and in this case requires 400 storage
elements.  Maybe the compiler is trying to store the offset computed from the
two indicies in a single byte as well, and that won't work.  Might I suggest
trying it with the array dimensioned to 4x50?  At least you'll have fewer
than 256 array elements, but then I wonder how it might handle signed versus
unsigned integers?  You might need to have fewer than 128 array elements.  If
it still fails, then I'd say you have good grounds for a complaint.  Otherwise,
using INTEGER*2 (or even the ANSI standard INTEGER) seems like a small price
to pay to get a program working.

bcphyagi@Twg-S5.uucp (Stephen Walton) (09/23/90)

In article <9504@uhccux.uhcc.Hawaii.Edu> tholen@uhccux.uhcc.Hawaii.Edu
(David Tholen) writes:

>Hmm.  Interesting.  An INTEGER*1 variable can have only 256 discrete values,

Actually, INTEGER*1 variables are signed in MS Fortran, so their range is
-128 to +127.  Beware.
--
Stephen R. Walton, Dept. of Physics and Astronomy, Cal State Northridge
I am srw@csun.edu no matter WHAT the stupid From: line says!

bcphyagi@Twg-S5.uucp (Stephen Walton) (09/23/90)

In article <2150@bnlux0.bnl.gov> gill@bnlux0.bnl.gov (ronald gill) writes:

>I tried to email, but it bounced back.

Note my .signature.  I've also initialized the Reply-To line.

>I had a similar FP problem
>with a large program using MicroSoft FORTRAN 4.0...
>I solved it by compiling with the HUGE attribute,

This occured to me, too.  Fact is, the offending program was sending a
150 by 150 REAL array to a routine compiled without the HUGE attribute,
though it only used about a 105 by 105 submatrix.  I re-dimensioned
the array to 127 by 127, reducing its size to less than 64K.  Still fails.

More news:  the test program fails on a no-name Taiwanese Turbo AT clone,
but works on a genuine IBM PC/AT and an Everex 386 Step 20.  I checked
on Compuserve, and there is a Microsoft tech note there about similar
trouble.  They admit a bug in their compiler, fixed in V5.00 and with
the FPFIX disk you can get from Microsoft, involving missing FWAIT
instructions.  They speculate that AT-type machines, such as old Compaq's,
might have ROM BIOS bugs, and specifically mention Phoenix BIOS V1.46
as a problem source.  Now, the clone has V3.08 of the ROM BIOS, so
that shouldn't be the trouble with my code.  Nevertheless, I'm willing
to believe, for the moment, that it is a hardware problem and not a
Microsoft bug.  Any other ideas/suggestions out there?
--
Stephen R. Walton, Dept. of Physics and Astronomy, Cal State Northridge
I am srw@csun.edu no matter WHAT the stupid From: line says!