1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma weak modf = __modf 32 #pragma weak _modf = __modf 33 34 /* 35 * modf(x, iptr) decomposes x into an integral part and a fractional 36 * part both having the same sign as x. It stores the integral part 37 * in *iptr and returns the fractional part. 38 * 39 * If x is infinite, modf sets *iptr to x and returns copysign(0.0,x). 40 * If x is NaN, modf sets *iptr to x and returns x. 41 * 42 * If x is a signaling NaN, this code does not attempt to raise the 43 * invalid operation exception. 44 */ 45 46 #include "libm.h" 47 48 double 49 __modf(double x, double *iptr) 50 { 51 union { 52 unsigned i[2]; 53 double d; 54 } xx, yy; 55 56 unsigned hx, s; 57 58 xx.d = x; 59 hx = xx.i[HIWORD] & ~0x80000000; 60 61 if (hx >= 0x43300000) { /* x is NaN, infinite, or integral */ 62 *iptr = x; 63 64 if (hx < 0x7ff00000 || (hx == 0x7ff00000 && xx.i[LOWORD] == 65 0)) { 66 xx.i[HIWORD] &= 0x80000000; 67 xx.i[LOWORD] = 0; 68 } 69 70 return (xx.d); 71 } 72 73 if (hx < 0x3ff00000) { /* |x| < 1 */ 74 xx.i[HIWORD] &= 0x80000000; 75 xx.i[LOWORD] = 0; 76 *iptr = xx.d; 77 return (x); 78 } 79 80 /* split x at the binary point */ 81 s = xx.i[HIWORD] & 0x80000000; 82 83 if (hx < 0x41400000) { 84 yy.i[HIWORD] = xx.i[HIWORD] & ~((1 << (0x413 - (hx >> 20))) - 85 1); 86 yy.i[LOWORD] = 0; 87 } else { 88 yy.i[HIWORD] = xx.i[HIWORD]; 89 yy.i[LOWORD] = xx.i[LOWORD] & ~((1 << (0x433 - (hx >> 20))) - 90 1); 91 } 92 93 *iptr = yy.d; 94 xx.d -= yy.d; 95 xx.i[HIWORD] = (xx.i[HIWORD] & ~0x80000000) | s; 96 /* keep sign of x */ 97 return (xx.d); 98 }