xref: /csrg-svn/lib/libc/quad/fixunsdfdi.c (revision 53437)
1*53437Sbostic /*-
2*53437Sbostic  * Copyright (c) 1992 The Regents of the University of California.
3*53437Sbostic  * All rights reserved.
4*53437Sbostic  *
5*53437Sbostic  * %sccs.include.redist.c%
6*53437Sbostic  */
7*53437Sbostic 
8*53437Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*53437Sbostic static char sccsid[] = "@(#)fixunsdfdi.c	5.1 (Berkeley) 05/12/92";
10*53437Sbostic #endif /* LIBC_SCCS and not lint */
11*53437Sbostic 
12*53437Sbostic #include "longlong.h"
13*53437Sbostic 
14*53437Sbostic #define HIGH_WORD_COEFF (((long long) 1) << BITS_PER_WORD)
15*53437Sbostic 
16*53437Sbostic long long
17*53437Sbostic __fixunsdfdi (a)
18*53437Sbostic      double a;
19*53437Sbostic {
20*53437Sbostic   double b;
21*53437Sbostic   unsigned long long v;
22*53437Sbostic 
23*53437Sbostic   if (a < 0)
24*53437Sbostic     return 0;
25*53437Sbostic 
26*53437Sbostic   /* Compute high word of result, as a flonum.  */
27*53437Sbostic   b = (a / HIGH_WORD_COEFF);
28*53437Sbostic   /* Convert that to fixed (but not to long long!),
29*53437Sbostic      and shift it into the high word.  */
30*53437Sbostic   v = (unsigned long int) b;
31*53437Sbostic   v <<= BITS_PER_WORD;
32*53437Sbostic   /* Remove high part from the double, leaving the low part as flonum.  */
33*53437Sbostic   a -= (double)v;
34*53437Sbostic   /* Convert that to fixed (but not to long long!) and add it in.
35*53437Sbostic      Sometimes A comes out negative.  This is significant, since
36*53437Sbostic      A has more bits than a long int does.  */
37*53437Sbostic   if (a < 0)
38*53437Sbostic     v -= (unsigned long int) (- a);
39*53437Sbostic   else
40*53437Sbostic     v += (unsigned long int) a;
41*53437Sbostic   return v;
42*53437Sbostic }
43