Re: Strange (long double) results from simple program



On Wed, 1 Apr 2009 14:06:02 -0500 (CDT), JohnCc
<john.coppens@xxxxxxxxx> wrote in comp.lang.c.moderated:

From a simple program in the online C-book (example 2.2), I get the
strangest results. The long double type, generates huge numbers, but
no error messages anywhere (not during compile, not runtime).

This is the program

#include <stdio.h>
#include <stdlib.h>

#define BOILING 212 /* degrees Fahrenheit */

main(){
float f_var; double d_var; long double l_d_var;
int i;

i = 0;
printf("Fahrenheit to Centigrade\n");
while(i <= BOILING){
l_d_var = 5*(i-32);
l_d_var = l_d_var/9;
d_var = l_d_var;
f_var = l_d_var;
printf("%d %f %f %lf\n", i,
f_var, d_var, l_d_var);
i = i+1;
}
exit(EXIT_SUCCESS);
}

And these are some of the results:

Fahrenheit to Centigrade
0 -17.777779 -17.777778 -0.000000
1 -17.222221 -17.222222 -0.000000
2 -16.666666 -16.666667 -0.000000
3 -16.111111 -16.111111 -0.000000
4 -15.555555 -15.555556
-21158078573198698010289181798401627640826271264225109152718092137403310882789368269967132366042310659839520335449801499542712855933823493401892528699555982744994011141399905815534630616622337356677259919585412318801879244214477032189928538764541847125736715941569320682782720.000000
5 -15.000000 -15.000000
-3105036184601417870297958976925005110513772034233393222278104076052101905372753772661756817657292955900975461394262146412343160088229628782888574550082362278408909952041699811100530571263196889650525998387432937501785693707632115712.000000
6 -14.444445 -14.444444
-495056490627408307874874185898572965162613604940303530230543732449907887934907546373606152585583704142214368799990922087963668020925429090978175584810001647296520383031864258189837186629632.000000
7 -13.888889 -13.888889
-77696852807864696768906283995214298977926968947698705726466606717705507797505091262825977589858299299966539665305932879793910044197207024945070080.000000
8 -13.333333 -13.333333
-11945305291614955126542043616649513276139111789490344052191740808676600059008889184485350614070737240064.000000
9 -12.777778 -12.777778
-1785486715843322607671496364043507394929446073619499616043008.000000
10 -12.222222 -12.222222 -272217577476616640.000000
11 -11.666667 -11.666667 -0.000000
12 -11.111111 -11.111111 -0.000000
13 -10.555555 -10.555556 -0.000000


These results go on to 212 degrees, repeating some of these problems.

Why is this? (I'm running gcc 4.2.3)

Thanks in advance.
John

What platform are you running gcc 4.2.3 on, and what library are you
using? Your question's headers indicate you posted from a box running
Windows.

Some of the ports of gcc to Windows, such as MinGW, do not provide a
library and use Microsoft's C runtime. When Microsoft started its
32-bit compiler line for Windows, they made a marketing decision to
make long double in its all Windows compilers the x86 64-bit floating
point type, the same is double. This is, unfortunately, allowed by
the C standard, which requires long double to be no higher in
precision than double, even when the hardware supports a higher
precision type.

In any case, gcc is passing 80-bit x86 extended precision floating
point types. If the library is expecting 64-bit x86 floating point
types, undefined behavior ensues, and might explain what you are
seeing.

Microsoft's web page http://support.microsoft.com/kb/129209 explains
this.

I love the wording:

"With the 16-bit Microsoft C/C++ compilers, long doubles are stored as
80- bit (10-byte) data types. Under Windows NT, in order to be
compatible with other non-Intel floating point implementations, the
80-bit long double format is aliased to the 64-bit (8-byte) double
format."

Noticed that Microsoft decided, a long time ago, that it was more
important to force compatibility across all Windows NT implementations
(most of which other than x86 Microsoft abandoned years ago), than it
was to allow the programmer to use his own judgment, especially if he
would never need to port to another processor with its own
implementation of Windows.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
--
comp.lang.c.moderated - moderation address: clcm@xxxxxxxxxxxx -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
.



Relevant Pages

  • Re: Breaking the 2GB barrier
    ... 32 bit Windows: ... If you really need more than this, you'll have to compile your application with the x64 flag, to prevent your application to run on X86. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: making an exe file
    ... i never looked at x86 ... > is it possible to write asm code in a text file, and compile (with a ... and run the program in windows 95 or windows xp? ...
    (comp.lang.asm.x86)
  • making an exe file
    ... i never looked at x86 ... is it possible to write asm code in a text file, and compile (with a ... and run the program in windows 95 or windows xp? ...
    (comp.lang.asm.x86)
  • Re: making an exe file
    ... i never looked at x86 ... > is it possible to write asm code in a text file, and compile (with a ... and run the program in windows 95 or windows xp? ...
    (comp.lang.asm.x86)
  • Re: Is CMUCL insane? P.S. Me vs. CLM (Common Lisp Music)
    ... Or to build Windows without a working version of Windows. ... why are you trying to compile CMUCL?" ... let's assume I use Linux and not an emulator here... ...
    (comp.lang.lisp)