1112158Sdas/* @(#)s_frexp.c 5.1 93/09/24 */ 2112158Sdas/* 3112158Sdas * ==================================================== 4112158Sdas * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5112158Sdas * 6112158Sdas * Developed at SunPro, a Sun Microsystems, Inc. business. 7112158Sdas * Permission to use, copy, modify, and distribute this 8112158Sdas * software is freely granted, provided that this notice 9112158Sdas * is preserved. 10112158Sdas * ==================================================== 11112158Sdas */ 12112158Sdas 13112158Sdas#include <sys/cdefs.h> 14112158Sdas#if defined(LIBM_SCCS) && !defined(lint) 15112158Sdas__RCSID("$NetBSD: s_frexp.c,v 1.14 2020/01/30 20:31:50 joerg Exp $"); 16112158Sdas#endif 17112158Sdas 18112158Sdas/* 19112158Sdas * for non-zero x 20112158Sdas * x = frexp(arg,&exp); 21112158Sdas * return a double fp quantity x such that 0.5 <= |x| <1.0 22112158Sdas * and the corresponding binary exponent "exp". That is 23112158Sdas * arg = x*2^exp. 24112158Sdas * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg 25112158Sdas * with *exp=0. 26112158Sdas */ 27112158Sdas 28112158Sdas#include "math.h" 29165743Sdas#include "math_private.h" 30165743Sdas 31112158Sdas#ifndef __HAVE_LONG_DOUBLE 32112158Sdas__strong_alias(frexpl, frexp) 33112158Sdas#endif 34112158Sdas 35112158Sdasstatic const double 36112158Sdastwo54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ 37112158Sdas 38112158Sdasdouble 39112158Sdasfrexp(double x, int *eptr) 40112158Sdas{ 41112158Sdas int32_t hx, ix, lx; 42112158Sdas EXTRACT_WORDS(hx,lx,x); 43112158Sdas ix = 0x7fffffff&hx; 44112158Sdas *eptr = 0; 45112158Sdas if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */ 46112158Sdas if (ix<0x00100000) { /* subnormal */ 47112158Sdas x *= two54; 48112158Sdas GET_HIGH_WORD(hx,x); 49112158Sdas ix = hx&0x7fffffff; 50112158Sdas *eptr = -54; 51112158Sdas } 52112158Sdas *eptr += ((uint32_t)ix>>20)-1022; 53112158Sdas hx = (hx&0x800fffff)|0x3fe00000; 54112158Sdas SET_HIGH_WORD(x,hx); 55112158Sdas return x; 56112158Sdas} 57112158Sdas