Conversion of unsigned long to double

Niels J|rgen Kruse njk at freja.diku.dk
Sun Apr 23 23:14:13 AEST 1989


tvdl at 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 <stdio.h>
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 at diku.dk
Mail         : Tustrupvej 7, 2 tv, 2720 Vanlose, Denmark



More information about the Comp.lang.c mailing list