/*- * Copyright (c) 1992, 1993 * 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. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$OpenBSD: fixunsdfdi.c,v 1.6 2004/10/17 17:49:21 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include "quad.h" #define ONE_FOURTH ((int)1 << (INT_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(double x) { union uu t; unsigned int tmp; if (x < 0) return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */ #ifdef notdef /* this falls afoul of a GCC bug */ if (x >= UQUAD_MAX) return (UQUAD_MAX); #else /* so we wire in 2^64-1 instead */ if (x >= 18446744073709551615.0) /* XXX */ return (UQUAD_MAX); #endif /* * Now we know that 0 <= x <= 18446744073709549568. The upper * limit is one ulp less than 18446744073709551615 tested for above. * Dividing this by 2^32 will *not* round irrespective of any * rounding modes (except if the result is an IEEE denorm). * Furthermore, the quotient will fit into a 32-bit integer. */ tmp = x / ONE; t.ul[L] = (unsigned int) (x - tmp * ONE); t.ul[H] = tmp; return (t.uq); }