12116Sjkh/* @(#)s_modf.c 5.1 93/09/24 */ 22116Sjkh/* 32116Sjkh * ==================================================== 42116Sjkh * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 52116Sjkh * 62116Sjkh * Developed at SunPro, a Sun Microsystems, Inc. business. 72116Sjkh * Permission to use, copy, modify, and distribute this 88870Srgrimes * software is freely granted, provided that this notice 92116Sjkh * is preserved. 102116Sjkh * ==================================================== 112116Sjkh */ 122116Sjkh 132116Sjkh#ifndef lint 1450476Speterstatic char rcsid[] = "$FreeBSD$"; 152116Sjkh#endif 162116Sjkh 172116Sjkh/* 188870Srgrimes * modf(double x, double *iptr) 192116Sjkh * return fraction part of x, and return x's integral part in *iptr. 202116Sjkh * Method: 212116Sjkh * Bit twiddling. 222116Sjkh * 232116Sjkh * Exception: 242116Sjkh * No exception. 252116Sjkh */ 262116Sjkh 272116Sjkh#include "math.h" 282116Sjkh#include "math_private.h" 292116Sjkh 302116Sjkhstatic const double one = 1.0; 312116Sjkh 3297413Salfreddouble 3397413Salfredmodf(double x, double *iptr) 342116Sjkh{ 352116Sjkh int32_t i0,i1,j0; 362116Sjkh u_int32_t i; 372116Sjkh EXTRACT_WORDS(i0,i1,x); 382116Sjkh j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ 392116Sjkh if(j0<20) { /* integer part in high x */ 402116Sjkh if(j0<0) { /* |x|<1 */ 412116Sjkh INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ 422116Sjkh return x; 432116Sjkh } else { 442116Sjkh i = (0x000fffff)>>j0; 452116Sjkh if(((i0&i)|i1)==0) { /* x is integral */ 462116Sjkh u_int32_t high; 472116Sjkh *iptr = x; 482116Sjkh GET_HIGH_WORD(high,x); 492116Sjkh INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ 502116Sjkh return x; 512116Sjkh } else { 522116Sjkh INSERT_WORDS(*iptr,i0&(~i),0); 532116Sjkh return x - *iptr; 542116Sjkh } 552116Sjkh } 562116Sjkh } else if (j0>51) { /* no fraction part */ 572116Sjkh u_int32_t high; 58165838Sdas if (j0 == 0x400) { /* inf/NaN */ 59165838Sdas *iptr = x; 60165838Sdas return 0.0 / x; 61165838Sdas } 622116Sjkh *iptr = x*one; 632116Sjkh GET_HIGH_WORD(high,x); 642116Sjkh INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ 652116Sjkh return x; 662116Sjkh } else { /* fraction part in low x */ 672116Sjkh i = ((u_int32_t)(0xffffffff))>>(j0-20); 682116Sjkh if((i1&i)==0) { /* x is integral */ 692116Sjkh u_int32_t high; 702116Sjkh *iptr = x; 712116Sjkh GET_HIGH_WORD(high,x); 722116Sjkh INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ 732116Sjkh return x; 742116Sjkh } else { 752116Sjkh INSERT_WORDS(*iptr,i0,i1&(~i)); 762116Sjkh return x - *iptr; 772116Sjkh } 782116Sjkh } 792116Sjkh} 80