The release notes for the 3.51 c compiler contain a statement to the effect that double precision floating point math was broken because someone had mistakenly defined HUGE as MAXFLOAT instead of MAXDOUBLE (strange that they never fixed this - the sccs header on is very old). The suggested fix was to write a matherr() for any program using doubles. The problem with this is that functions in libc.a like frexp(), etc. don't call matherr--only the ones in libm.a. This creates the rather hairy situation that one set of functions thinks HUGE is ~1e308 and the other group thinks it's ~3e38. A related problem is that you can't call strtol() with an argument over 3e38. I decided that the most rational thing to do would be to change and patch the functions to replace MAXFLOAT by MAXDOUBLE. When I started to do this I also found a kludge in that defined MAXDOUBLE as ~1e307 instead of ~1e308 for the 3b1, along with a note to the effect that this "papers around a bug in frexp.c that should be fixed." Upon closer examination, I found that: a) There is no frexp.o in libc.a b) A quick test revealed that frexp() worked fine c) A test of ldexp() showed that it was broken After patching all the relevant files, ldexp() still couldn't handle large values, so by doing a sdb trace on the test, I found it was doing a couple compares to constants which didn't make sense for either MAXFLOAT or MAXDOUBLE. After patching those two, all of the double math functions now work correctly up to MAXDOUBLE, and overflows return HUGE=~1e308 (I took out the 1e307 kludge in . Obviously, I can't distribute the AT&T libraries themselves, but the procedure for fixing them is easy enough: Be sure to back up the libraries carefully before making any changes. Also, be sure to check out shlib VERY CAREFULLY before you try to install the new version. If shlib is broken, you may not be able to run any of the system utilities when you reboot, necessitating hacking around with a bootable floppy filesystem to fix things. I wrote a pair of small c programs (handy for other things as well) called bin2hex.c and hex2bin.c: (or you can use GNU EMACS) /* bin2hex.c */ #include main() { unsigned char outstr[5]; unsigned short foo; register short i,f; f=0; while(read(0,&foo,2)!=NULL){ sprintf(outstr,"%4x",foo); for(i=0;i<4;i++)if(outstr[i]==' ')outstr[i]='0'; (f<15)?(printf("%4s ",outstr),f++):(printf("%4s\n",outstr),f=0); } if(f>0) printf("\n"); } /* hex2bin.c */ #include main() { unsigned char instr[5]; unsigned short foo; while(scanf("%4s",instr)!=EOF){ foo=(short)strtol(instr,(char **)NULL,16); write(1,&foo,2); } } I used these to convert the library files to hexadecimal text files. The files that need to be changed are: /lib/shlib In /lib/libc.a: ptod.o ldexp.o In /lib/libp/libc.a: ptod.o ldexp.o In /lib/libm.a: gamma.o hypot.o jn.o j0.o j1.o pow.o log.o tan.o sinh.o exp.o fpa_err.o The files in the lib*.a files were extracted with ar -x archive file[s]. The following patches were made: All 47ef ffff e000 0000 --> 7fef ffff ffff ffff All c7ef ffff e000 0000 --> ffef ffff ffff ffff and, for ldexp(), in shlib and libc.a: (This is the only place in shlib where these are found) 0c80 0000 03ff --> 0c80 0000 0400 0c80 ffff fbcc --> 0c80 ffff fbcd /*corrected 6/16/90*/ In : #define HUGE MAXDOUBLE In : #if u3b || mc68k * MAXDOUBLE - The largest double ((_EXPBASE ** (DMAXEXP + 1)) - 1) #define MAXDOUBLE 1.79769313486231570e308 ------------------- Convert the files back to binary with hex2bin and test them out. This should give you a floating point math library that works "as advertized." *****NOTICE*****DISCLAIMER*****NOTICE*****DISCLAIMER*****NOTICE***** While I have tested these changes fairly thoroughly, and they seem to work O.K., I accept no responsibility for any consequences resulting from any application of the above information. I hereby release the above into the public domain. You can use it, abuse it, or whatever turns you on: just don't blame me! Since the above procedure does not involve regeneration of source code, there should be no problems with violation of your software license agreement. Please note, however, that AT&T states that "A user-modified libc.a or shared library will not be supported." Therefore, you should have the original libraries available for debugging purposes before consulting AT&T for support. Jim Adams adams@ucunix.san.uc.edu Department of Physiology and Biophysics University of Cincinnati