davidgiven / ack

The Amsterdam Compiler Kit
http://tack.sf.net
Other
420 stars 59 forks source link

real numbers may have incorrect field width in pascal write() statement #216

Open tevorbl opened 4 years ago

tevorbl commented 4 years ago

for example, on linux386:

program t(output);
begin
   writeln(1/3:8);  {specify fieldwidth = 8}
end.

output is: 3.3e-001 <--- fieldwidth is 9 chars

I think the issue is that in lang/pc/libpc/wrr.c it is assumed that exponents have only 2 digits, but linux 386 (& probably some other platforms) need 3 digits.

I fixed it by adding this code to wrr.c

#if __STDC__
#include <float.h>
#if DBL_MAX_10_EXP >= 1000
#undef EXP_DIGS
#define EXP_DIGS 4
#elif DBL_MAX_10_EXP >= 100
#undef EXP_DIGS
#define EXP_DIGS 3
#endif
#endif

and

       if ((i = w - (4+EXP_DIGS)) < 2)
                i = 2;

Works for me.

The completed version of wrr.c is attached.

PS. I have a feeling there a way to test this on other platforms using qemu, but I can't figure out how. Anyone got a quick overview where to start?

wrr.c.txt

tevorbl commented 4 years ago

OK, the emulators are deep inside the tmp directory, eg for m68k it's here:

.../tmp/ack-build/obj/plat/linux68k/emu/emu68k/emu68k

Found only a few have emulators there: linux 386, linux68k, cpm, & pcdos

cpm doesn't have FP, so can't test there. (but there are FP packages for the 8080, see here --> http://retrotechnology.com/herbs_stuff/float.html)

linux386 has the bug as reported above.

linux 68k doesn't have FP. I updated linux68k platform to include FP, & bug is repeatable there. (PR on its way)

pcdos platform prints real numbers something like this --> ////.//. counting the characters confirms the bug. And reveals another one.

Next step: try to configure platforms to make doubles 4 bytes instead of 8 and see what happens.