1  /* s_frexpl.c -- long double version of s_frexp.c.
       2   */
       3  
       4  /*
       5   * ====================================================
       6   * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
       7   *
       8   * Developed at SunPro, a Sun Microsystems, Inc. business.
       9   * Permission to use, copy, modify, and distribute this
      10   * software is freely granted, provided that this notice
      11   * is preserved.
      12   * ====================================================
      13   */
      14  
      15  #if defined(LIBM_SCCS) && !defined(lint)
      16  static char rcsid[] = "$NetBSD: $";
      17  #endif
      18  
      19  /*
      20   * for non-zero x
      21   *	x = frexpl(arg,&exp);
      22   * return a long double fp quantity x such that 0.5 <= |x| <1.0
      23   * and the corresponding binary exponent "exp". That is
      24   *	arg = x*2^exp.
      25   * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg
      26   * with *exp=0.
      27   */
      28  
      29  #include <float.h>
      30  #include <math.h>
      31  #include <math_private.h>
      32  #include <libm-alias-ldouble.h>
      33  
      34  static const long double
      35  #if LDBL_MANT_DIG == 64
      36  two65 =  3.68934881474191032320e+19L; /* 0x4040, 0x80000000, 0x00000000 */
      37  #else
      38  # error "Cannot handle this MANT_DIG"
      39  #endif
      40  
      41  
      42  long double __frexpl(long double x, int *eptr)
      43  {
      44  	uint32_t se, hx, ix, lx;
      45  	GET_LDOUBLE_WORDS(se,hx,lx,x);
      46  	ix = 0x7fff&se;
      47  	*eptr = 0;
      48  	if(ix==0x7fff||((ix|hx|lx)==0)) return x + x;	/* 0,inf,nan */
      49  	if (ix==0x0000) {		/* subnormal */
      50  	    x *= two65;
      51  	    GET_LDOUBLE_EXP(se,x);
      52  	    ix = se&0x7fff;
      53  	    *eptr = -65;
      54  	}
      55  	*eptr += ix-16382;
      56  	se = (se & 0x8000) | 0x3ffe;
      57  	SET_LDOUBLE_EXP(x,se);
      58  	return x;
      59  }
      60  libm_alias_ldouble (__frexp, frexp)