From: Chris Torek Date: Wed, 8 Jul 1992 02:49:04 +0000 (-0800) Subject: date and time created 92/07/07 11:49:04 by torek X-Git-Tag: BSD-4_4-Snapshot-Development~6114 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/9ef392c7e1b390bc200d01f17f9e0be7ba158145 date and time created 92/07/07 11:49:04 by torek SCCS-vsn: lib/libc/quad/fixunssfdi.c 5.1 --- diff --git a/usr/src/lib/libc/quad/fixunssfdi.c b/usr/src/lib/libc/quad/fixunssfdi.c new file mode 100644 index 0000000000..235859721e --- /dev/null +++ b/usr/src/lib/libc/quad/fixunssfdi.c @@ -0,0 +1,69 @@ +/*- + * 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[] = "@(#)fixunssfdi.c 5.1 (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 float to (unsigned) quad. We do most of our work in double, + * out of sheer paranoia. + * + * Not sure what to do with negative numbers---for now, anything out + * of range becomes UQUAD_MAX. + * + * N.B.: must use new ANSI syntax (sorry). + */ +u_quad_t +__fixunssfdi(float f) +{ + double x, toppart; + union uu t; + + if (f < 0) + return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */ + if (f >= UQUAD_MAX) + return (UQUAD_MAX); + x = f; + /* + * 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); +}