Path: santra!tut!draken!kth!sunic!dkuug!freja!njk From: njk@freja.diku.dk (Niels J|rgen Kruse) Newsgroups: comp.lang.c Subject: Re: Conversion of unsigned long to double Message-ID: <4612@freja.diku.dk> Date: 23 Apr 89 13:14:13 GMT References: <515@bsiao.UUCP> Organization: DIKU, U of Copenhagen, DK Lines: 81 tvdl@bsiao.UUCP (Timo van der Laan) writes: >The C-compiler for IX370 (running on a 9370 machine) treats an >unsigned long as a signed long if that unsigned long is assigned to >a double. (See the program below). >Is this behavior permitted in ANSI? It has always been a bug, just a very common one. The only reliable way to convert an unsigned long to double, if you want your code to be compiled correctly by pcc derived compilers, is to write something like #define ul_to_dbl(ul) \ ((ul)&(unsigned long)-1/2+1 \ ? (long)((ul)&(unsigned long)-1/2) \ + 2.0 * (long)((unsigned long)-1/4+1) \ : (long)(ul)) (...) double d; unsigned long ul; (...) d = ul_to_dbl(ul); >**** program **** (deleted) >**** Output on IBM 9370 (IX370)**** | **** Output on a Vax (4.3 bsd) **** (showing correct conversion on Bsd 4.3 Vax and incorrect on IBM 9370) Lest you should harbour any delusions that the Bsd 4.3 cc handles unsigned arithmetic and conversions correctly in general, try running this little program : ------------- demo program ----------- #include main() { static unsigned ut[5] = {0,0,-1,0,0}; double dblt[5]; int i = 0; printf ("First test : "); if ((unsigned)-1 < 1) printf ("*splat*\n"); else printf ("correct.\n"); printf ("Second test : the same value assigned to dblt[0] and dblt[1]\n"); dblt[i] = ut[2]; dblt[++i] = ut[2]; printf (" dblt[0] = %12.10lg, dblt[1] = %12.10lg\n",dblt[0],dblt[1]); printf ("Third test : assigning ut[i] to dblt[i]\n"); for (i = 0; i < 5; i++) dblt[i] = ut[i]; for (i = 0; i < 5; i++) printf (" ut[%d] = %12u, dblt[%d] = %12.10lg\n",i,ut[i],i,dblt[i]); } ------------- end program ------------ ----------- Bsd 4.3 Vax output ------- First test : *splat* Second test : the same value assigned to dblt[0] and dblt[1] dblt[0] = 4294967295, dblt[1] = 2147483519 Third test : assigning ut[i] to dblt[i] ut[0] = 0, dblt[0] = 0 ut[1] = 0, dblt[1] = -1.701411733e+38 ut[2] = 4294967295, dblt[2] = 0 ut[3] = 0, dblt[3] = 0 ut[4] = 0, dblt[4] = 0 --------------- end output ----------- Needless to say, behaviour like this can leed to ... um, captivating debugging sessions. >-- > Timo van der Laan, Postbank N.V., room 4.94 ...mcvax!hp4nl!bsiao!tvdl > Pb 21009 > 1000 EX AMSTERDAM Phone: + 31 20 5843175 > "Real programmers don't wear ties" -- Name : Niels J|rgen Kruse Organization : DIKU, University of Copenhagen, Computer Science dept. Email : njk@diku.dk Mail : Tustrupvej 7, 2 tv, 2720 Vanlose, Denmark