192b93b37SDavid Schultz /*- 292b93b37SDavid Schultz * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> 392b93b37SDavid Schultz * All rights reserved. 492b93b37SDavid Schultz * 592b93b37SDavid Schultz * Redistribution and use in source and binary forms, with or without 692b93b37SDavid Schultz * modification, are permitted provided that the following conditions 792b93b37SDavid Schultz * are met: 892b93b37SDavid Schultz * 1. Redistributions of source code must retain the above copyright 992b93b37SDavid Schultz * notice, this list of conditions and the following disclaimer. 1092b93b37SDavid Schultz * 2. Redistributions in binary form must reproduce the above copyright 1192b93b37SDavid Schultz * notice, this list of conditions and the following disclaimer in the 1292b93b37SDavid Schultz * documentation and/or other materials provided with the distribution. 1392b93b37SDavid Schultz * 1492b93b37SDavid Schultz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1592b93b37SDavid Schultz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1692b93b37SDavid Schultz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1792b93b37SDavid Schultz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1892b93b37SDavid Schultz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1992b93b37SDavid Schultz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2092b93b37SDavid Schultz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2192b93b37SDavid Schultz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2292b93b37SDavid Schultz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2392b93b37SDavid Schultz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2492b93b37SDavid Schultz * SUCH DAMAGE. 2592b93b37SDavid Schultz */ 2692b93b37SDavid Schultz 2792b93b37SDavid Schultz #include <sys/cdefs.h> 2892b93b37SDavid Schultz __FBSDID("$FreeBSD$"); 2992b93b37SDavid Schultz 3092b93b37SDavid Schultz #include <float.h> 3192b93b37SDavid Schultz #include <inttypes.h> 3292b93b37SDavid Schultz #include <limits.h> 3392b93b37SDavid Schultz #include <math.h> 3492b93b37SDavid Schultz #include <stdlib.h> 3592b93b37SDavid Schultz #include "fpmath.h" 3692b93b37SDavid Schultz #include "gdtoaimp.h" 3792b93b37SDavid Schultz 3892b93b37SDavid Schultz /* 3992b93b37SDavid Schultz * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(), 4092b93b37SDavid Schultz * except that the floating point argument is passed by reference. 4192b93b37SDavid Schultz * When dtoa() is passed a NaN or infinity, it sets expt to 9999. 4292b93b37SDavid Schultz * However, a long double could have a valid exponent of 9999, so we 4392b93b37SDavid Schultz * use INT_MAX in ldtoa() instead. 4492b93b37SDavid Schultz */ 4592b93b37SDavid Schultz char * 4692b93b37SDavid Schultz __ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, 4792b93b37SDavid Schultz char **rve) 4892b93b37SDavid Schultz { 4992b93b37SDavid Schultz static FPI fpi = { 5092b93b37SDavid Schultz LDBL_MANT_DIG, /* nbits */ 5192b93b37SDavid Schultz LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */ 5292b93b37SDavid Schultz LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */ 5392b93b37SDavid Schultz FPI_Round_near, /* rounding */ 5492b93b37SDavid Schultz #ifdef Sudden_Underflow /* unused, but correct anyway */ 5592b93b37SDavid Schultz 1 5692b93b37SDavid Schultz #else 5792b93b37SDavid Schultz 0 5892b93b37SDavid Schultz #endif 5992b93b37SDavid Schultz }; 6092b93b37SDavid Schultz int be, kind; 6192b93b37SDavid Schultz char *ret; 6292b93b37SDavid Schultz union IEEEl2bits u; 6392b93b37SDavid Schultz uint32_t bits[(LDBL_MANT_DIG + 31) / 32]; 643e636fa0SJohn Birrell void *vbits = bits; 6592b93b37SDavid Schultz 6692b93b37SDavid Schultz u.e = *ld; 6792b93b37SDavid Schultz *sign = u.bits.sign; 6892b93b37SDavid Schultz be = u.bits.exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1); 6992b93b37SDavid Schultz LDBL_TO_ARRAY32(u, bits); 7092b93b37SDavid Schultz 7192b93b37SDavid Schultz switch (fpclassify(u.e)) { 7292b93b37SDavid Schultz case FP_NORMAL: 7392b93b37SDavid Schultz kind = STRTOG_Normal; 7492b93b37SDavid Schultz #ifdef LDBL_IMPLICIT_NBIT 7592b93b37SDavid Schultz bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32); 7692b93b37SDavid Schultz #endif /* LDBL_IMPLICIT_NBIT */ 7792b93b37SDavid Schultz break; 7892b93b37SDavid Schultz case FP_ZERO: 7992b93b37SDavid Schultz kind = STRTOG_Zero; 8092b93b37SDavid Schultz break; 8192b93b37SDavid Schultz case FP_SUBNORMAL: 8292b93b37SDavid Schultz kind = STRTOG_Denormal; 83d784b0c3SDavid Schultz #ifdef LDBL_IMPLICIT_NBIT 84d784b0c3SDavid Schultz be++; 85d784b0c3SDavid Schultz #endif 8692b93b37SDavid Schultz break; 8792b93b37SDavid Schultz case FP_INFINITE: 8892b93b37SDavid Schultz kind = STRTOG_Infinite; 8992b93b37SDavid Schultz break; 9092b93b37SDavid Schultz case FP_NAN: 9192b93b37SDavid Schultz kind = STRTOG_NaN; 9292b93b37SDavid Schultz break; 9392b93b37SDavid Schultz default: 9492b93b37SDavid Schultz abort(); 9592b93b37SDavid Schultz } 9692b93b37SDavid Schultz 973e636fa0SJohn Birrell ret = gdtoa(&fpi, be, vbits, &kind, mode, ndigits, decpt, rve); 9892b93b37SDavid Schultz if (*decpt == -32768) 9992b93b37SDavid Schultz *decpt = INT_MAX; 10092b93b37SDavid Schultz return ret; 10192b93b37SDavid Schultz } 102