gonzui


Format: Advanced Search

t2ex/bsd_source/lib/libc/src_bsd/stdlib/ldtoa.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*      $OpenBSD: ldtoa.c,v 1.1 2008/09/07 20:36:08 martynas Exp $   */
    2: /*-
    3:  * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
    4:  * All rights reserved.
    5:  *
    6:  * Redistribution and use in source and binary forms, with or without
    7:  * modification, are permitted provided that the following conditions
    8:  * are met:
    9:  * 1. Redistributions of source code must retain the above copyright
   10:  *    notice, this list of conditions and the following disclaimer.
   11:  * 2. Redistributions in binary form must reproduce the above copyright
   12:  *    notice, this list of conditions and the following disclaimer in the
   13:  *    documentation and/or other materials provided with the distribution.
   14:  *
   15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25:  * SUCH DAMAGE.
   26:  */
   27: 
   28: #include <sys/types.h>
   29: #ifndef __vax__
   30: #include <machine/ieee.h>
   31: #endif /* !__vax__ */
   32: #include <float.h>
   33: #include <inttypes.h>
   34: #include <limits.h>
   35: #include <math.h>
   36: #include <stdlib.h>
   37: #include "gdtoaimp.h"
   38: 
   39: #if (LDBL_MANT_DIG > DBL_MANT_DIG)
   40: 
   41: /*
   42:  * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(),
   43:  * except that the floating point argument is passed by reference.
   44:  * When dtoa() is passed a NaN or infinity, it sets expt to 9999.
   45:  * However, a long double could have a valid exponent of 9999, so we
   46:  * use INT_MAX in ldtoa() instead.
   47:  */
   48: char *
   49: __ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign,
   50:     char **rve)
   51: {
   52:         FPI fpi = {
   53:                 LDBL_MANT_DIG,                        /* nbits */
   54:                 LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */
   55:                 LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */
   56:                 FLT_ROUNDS,                     /* rounding */
   57: #ifdef Sudden_Underflow /* unused, but correct anyway */
   58:                 1
   59: #else
   60:                 0
   61: #endif
   62:         };
   63:         int be, kind;
   64:         char *ret;
   65:         struct ieee_ext *p = (struct ieee_ext *)ld;
   66:         uint32_t bits[(LDBL_MANT_DIG + 31) / 32];
   67:         void *vbits = bits;
   68: 
   69:         /*
   70:          * gdtoa doesn't know anything about the sign of the number, so
   71:          * if the number is negative, we need to swap rounding modes of
   72:          * 2 (upwards) and 3 (downwards).
   73:          */
   74:         *sign = p->ext_sign;
   75:         fpi.rounding ^= (fpi.rounding >> 1) & p->ext_sign;
   76: 
   77:         be = p->ext_exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1);
   78:         EXT_TO_ARRAY32(p, bits);
   79: 
   80:         switch (fpclassify(*ld)) {
   81:         case FP_NORMAL:
   82:                 kind = STRTOG_Normal;
   83: #ifdef EXT_IMPLICIT_NBIT
   84:                 bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32);
   85: #endif /* EXT_IMPLICIT_NBIT */
   86:                 break;
   87:         case FP_ZERO:
   88:                 kind = STRTOG_Zero;
   89:                 break;
   90:         case FP_SUBNORMAL:
   91:                 kind = STRTOG_Denormal;
   92:                 be++;
   93:                 break;
   94:         case FP_INFINITE:
   95:                 kind = STRTOG_Infinite;
   96:                 break;
   97:         case FP_NAN:
   98:                 kind = STRTOG_NaN;
   99:                 break;
  100:         default:
  101:                 /*abort()*/;
  102:         }
  103: 
  104:         ret = gdtoa(&fpi, be, vbits, &kind, mode, ndigits, decpt, rve);
  105:         if (*decpt == -32768)
  106:                 *decpt = INT_MAX;
  107:         return ret;
  108: }
  109: 
  110: #else   /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
  111: 
  112: char *
  113: __ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign,
  114:     char **rve)
  115: {
  116:         char *ret;
  117: 
  118:         ret = dtoa((double)*ld, mode, ndigits, decpt, sign, rve);
  119:         if (*decpt == 9999)
  120:                 *decpt = INT_MAX;
  121:         return ret;
  122: }
  123: 
  124: #endif  /* (LDBL_MANT_DIG == DBL_MANT_DIG) */