toma@sail.LABS.TEK.COM (Tom Almy) (02/05/91)
Microsoft C has been bad-mouthed here by myself and others over the years, but this past weekend I discovered at least one place where it beats the major competition -- the math library. Two cases: Case 1: { double x=1e200; printf("%g",x*x); } (With some compilers, the 80x87 has to have the overflow trap masked off). Microsoft C (V6.00A): prints +inf (correct!) Microway NDP C-386 (V1.4e): prints -*inf** (wrong sign!?!) Metaware High C DOS 386 (V1.62): prints infinity (correct!) Turbo C (C++ V1.0): hangs, requiring "three fingered salute". Zortech C (V2.18): prints 1.797693e+308 Case 2: { double x=1e50; x = sin(x); printf("%g", x);} ( matherr() function defined where available ) Microsoft: sine function causes error "Total loss of significance" (correct!) Microway: crashes, producing register dump, executing sine function. Metaware: with inline 80387 code, 1e50; with fp library, NaN (ok.) Turbo C: sine function causes error "Domain" (wrong error) Zortech C: prints garbage answer. A test of some other language compilers produced dismal results as well. Only Microsoft C worked. Tom Almy toma@sail.labs.tek.com Standard Disclaimers Apply -- Tom Almy toma@sail.labs.tek.com <<< Note new address Standard Disclaimers Apply
dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (02/05/91)
In article <8904@sail.LABS.TEK.COM> toma@sail.LABS.TEK.COM (Tom Almy) writes: >Microsoft C has been bad-mouthed here by myself and others over the years, >but this past weekend I discovered at least one place where it beats the >major competition -- the math library. Two cases: > >Case 1: { double x=1e200; printf("%g",x*x); } >(With some compilers, the 80x87 has to have the overflow trap masked off). I tried your tests in Turbo Pascal 6.0, and was pleasantly surprised at the results. (TP 6.0 has some real problems with esoteric floating point code.) > >Microsoft C (V6.00A): prints +inf (correct!) MSC may be correct for C, but TP prints 1.00000000E+0400, which is even more correct. (This is because TP promotes expressions to the 10 byte extended type.) When I forced the result to go into a double, I got an overflow error; when I masked those, I got INF. > >Case 2: { double x=1e50; x = sin(x); printf("%g", x);} >( matherr() function defined where available ) > >Microsoft: sine function causes error "Total loss of significance" (correct!) TP just gives an invalid operation error, or a NAN when masked. >A test of some other language compilers produced dismal results as well. >Only Microsoft C worked. And TP! Duncan Murdoch dmurdoch@watstat.waterloo.edu
kdq@demott.com (Kevin D. Quitt) (02/06/91)
In article <1991Feb5.020455.26710@maytag.waterloo.edu> dmurdoch@watstat.waterloo.edu (Duncan Murdoch) writes: >In article <8904@sail.LABS.TEK.COM> toma@sail.LABS.TEK.COM (Tom Almy) writes: >>Microsoft C has been bad-mouthed here by myself and others over the years, >>but this past weekend I discovered at least one place where it beats the >>major competition -- the math library. Two cases: >> >>Case 1: { double x=1e200; printf("%g",x*x); } >>(With some compilers, the 80x87 has to have the overflow trap masked off). > >I tried your tests in Turbo Pascal 6.0, and was pleasantly surprised at the >results. (TP 6.0 has some real problems with esoteric floating point code.) >> >>Microsoft C (V6.00A): prints +inf (correct!) > >MSC may be correct for C, but TP prints 1.00000000E+0400, which is even more >correct. (This is because TP promotes expressions to the 10 byte extended >type.) When I forced the result to go into a double, I got an overflow >error; when I masked those, I got INF. It's more correct mathematically, but not according to the C language spec. There *are* (non-standard) ways in MSC to use the 10-byte reals. -- _ Kevin D. Quitt demott!kdq kdq@demott.com DeMott Electronics Co. 14707 Keswick St. Van Nuys, CA 91405-1266 VOICE (818) 988-4975 FAX (818) 997-1190 MODEM (818) 997-4496 PEP last
6600m00n@ucsbuxa.ucsb.edu (Steelworker) (02/06/91)
In article <8904@sail.LABS.TEK.COM> toma@sail.LABS.TEK.COM (Tom Almy) writes: >Microsoft C has been bad-mouthed here by myself and others over the years, >but this past weekend I discovered at least one place where it beats the >major competition -- the math library. Two cases: >Case 1: { double x=1e200; printf("%g",x*x); } >(With some compilers, the 80x87 has to have the overflow trap masked off). First problem- the printf should read printf("%lg",x*x); ^ I have made this error enough times to preach about this one! Try your test's again with this and post the results. Robert Blair 6600m00n@ucsbuxa.ucsb.edu
dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (02/06/91)
In article <1991Feb5.184015.9539@demott.com> kdq@demott.com (Kevin D. Quitt) writes: >> >>MSC may be correct for C, but TP prints 1.00000000E+0400, which is even more >>correct. (This is because TP promotes expressions to the 10 byte extended >>type.) When I forced the result to go into a double, I got an overflow >>error; when I masked those, I got INF. > > It's more correct mathematically, but not according to the C language >spec. There *are* (non-standard) ways in MSC to use the 10-byte reals. Sure, I understand that. Just curious though: does the C standard address the problem of what to do when an expression overflows? That seems like such a machine dependent thing that I'd think it would be left up to the implementation, but you never know. Duncan Murdoch dmurdoch@watstat.waterloo.edu
kooijman@duteca (Richard Kooijman) (02/07/91)
6600m00n@ucsbuxa.ucsb.edu (Steelworker) writes: >In article <8904@sail.LABS.TEK.COM> toma@sail.LABS.TEK.COM (Tom Almy) writes: >>Case 1: { double x=1e200; printf("%g",x*x); } >>(With some compilers, the 80x87 has to have the overflow trap masked off). >First problem- the printf should read >printf("%lg",x*x); > ^ >I have made this error enough times to preach about this one! WRONG, the l modifier only applies to long int's and not floating point numbers. Richard.
ath@linkoping.telesoft.se (Anders Thulin) (02/07/91)
In article <8904@sail.LABS.TEK.COM> toma@sail.LABS.TEK.COM (Tom Almy) writes: >Case 1: { double x=1e200; printf("%g",x*x); } >(With some compilers, the 80x87 has to have the overflow trap masked off). > >Microsoft C (V6.00A): prints +inf (correct!) >Microway NDP C-386 (V1.4e): prints -*inf** (wrong sign!?!) >Metaware High C DOS 386 (V1.62): prints infinity (correct!) >Turbo C (C++ V1.0): hangs, requiring "three fingered salute". >Zortech C (V2.18): prints 1.797693e+308 Why is 'infinity' the correct answer? I don't think ANSI C says anything about that, so the Zortech answer may be 'as correct' as the Microsoft or Metware. >Case 2: { double x=1e50; x = sin(x); printf("%g", x);} >( matherr() function defined where available ) > >Microsoft: sine function causes error "Total loss of significance" (correct!) >Microway: crashes, producing register dump, executing sine function. >Metaware: with inline 80387 code, 1e50; with fp library, NaN (ok.) >Turbo C: sine function causes error "Domain" (wrong error) >Zortech C: prints garbage answer. A suggestion: In an ANSI C environment, you must clear errno before the invocation of sin, and test it afterwards to detect any errors. As I don't see it in your code, I suspect you didn't use it. Naturally, 'correctness' must be relative some standard. I assume ANSI C, but you may have chosen something different. -- Anders Thulin ath@linkoping.telesoft.se Telesoft Europe AB, Teknikringen 2B, S-583 30 Linkoping, Sweden
toma@sail.LABS.TEK.COM (Tom Almy) (02/11/91)
In article <730@castor.linkoping.telesoft.se> ath@linkoping.telesoft.se (Anders Thulin) writes: >In article <8904@sail.LABS.TEK.COM> toma@sail.LABS.TEK.COM (Tom Almy) writes: > >>Case 1: { double x=1e200; printf("%g",x*x); } >>(With some compilers, the 80x87 has to have the overflow trap masked off). >>Microsoft C (V6.00A): prints +inf (correct!) >>Microway NDP C-386 (V1.4e): prints -*inf** (wrong sign!?!) >>Metaware High C DOS 386 (V1.62): prints infinity (correct!) >>Turbo C (C++ V1.0): hangs, requiring "three fingered salute". >>Zortech C (V2.18): prints 1.797693e+308 >Why is 'infinity' the correct answer? I don't think ANSI C says >anything about that, so the Zortech answer may be 'as correct' as the >Microsoft or Metware. In every case IEEE floating point is used. The floating point co-processor generates the result "+inf". The Zortech runtime doesn't recognize the special value, but instead prints the largest float. "+inf" is more correct because that is the internally represented value, and is also indicative that overflow has occured. It is interesting to note that only the ZOrtech compiler does not mask overflow by default -- with the other compilers (which print "inf") you have to mask overflow to get the infinity result since they would otherwise abort with a fp overflow trap. >>Case 2: { double x=1e50; x = sin(x); printf("%g", x);} >>( matherr() function defined where available ) >>Microsoft: sine function causes error "Total loss of significance" (correct!) >>Microway: crashes, producing register dump, executing sine function. >>Metaware: with inline 80387 code, 1e50; with fp library, NaN (ok.) >>Turbo C: sine function causes error "Domain" (wrong error) >>Zortech C: prints garbage answer. >A suggestion: >In an ANSI C environment, you must clear errno before the invocation >of sin, and test it afterwards to detect any errors. As I don't see >it in your code, I suspect you didn't use it. Microsoft, Turbo, and Zortech provide matherr() functions which are supposed to trap the errors (in fact all but Zortech did). Neither Metaware nor Zortech set errno. I was able to get Zortech to indicate an error by telling the run time that no floating point was available -- it gives the error when the emulator is used! But that doesn't help performance. An investigation of this problem showed that the library implementers did not RTFM! The sine function (and some others) leave the argument untouched when out of range, but set a flag indicating failed reduction. These compilers just fail to check the flag. >Naturally, 'correctness' must be relative some standard. I assume ANSI C, >but you may have chosen something different. IMHO C is not my language of choice for numeric programs because it is so slopily defined (although I must admit ANSI C is improving). Expecting floating point errors to be handled might be asking too much, but as I said "Microsoft C actually does something better." Tom Almy toma@sail.labs.tek.com Standard Disclaimers Apply -- Tom Almy toma@sail.labs.tek.com Standard Disclaimers Apply