KNF, integrate with standard include files (quad -> quad_t etc.)
[unix-history] / usr / src / lib / libc / quad / fixunsdfdi.c
/*-
* Copyright (c) 1992 The Regents of the University of California.
* All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* %sccs.include.redist.c%
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)fixunsdfdi.c 5.4 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include "quad.h"
#define ONE_FOURTH (1 << (LONG_BITS - 2))
#define ONE_HALF (ONE_FOURTH * 2.0)
#define ONE (ONE_FOURTH * 4.0)
/*
* Convert double to (unsigned) quad.
* Not sure what to do with negative numbers---for now, anything out
* of range becomes UQUAD_MAX.
*/
u_quad_t
__fixunsdfdi(x)
double x;
{
double toppart;
union uu t;
if (x < 0)
return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */
if (x >= UQUAD_MAX)
return (UQUAD_MAX);
/*
* Get the upper part of the result. Note that the divide
* may round up; we want to avoid this if possible, so we
* subtract `1/2' first.
*/
toppart = (x - ONE_HALF) / ONE;
/*
* Now build a u_quad_t out of the top part. The difference
* between x and this is the bottom part (this may introduce
* a few fuzzy bits, but what the heck). With any luck this
* difference will be nonnegative: x should wind up in the
* range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN..
* 2*ULONG_MAX] instead.
*/
t.ul[H] = (unsigned long)toppart;
t.ul[L] = 0;
x -= (double)t.uq;
if (x < 0) {
t.ul[H]--;
x += ULONG_MAX;
}
if (x > ULONG_MAX) {
t.ul[H]++;
x -= ULONG_MAX;
}
t.ul[L] = (u_long)x;
return (t.uq);
}