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 __remainder = remainder 32 33 /* 34 * remainder(x,p) 35 * Code originated from 4.3bsd. 36 * Modified by K.C. Ng for SUN 4.0 libm. 37 * Return : 38 * returns x REM p = x - [x/p]*p as if in infinite precise arithmetic, 39 * where [x/p] is the (inifinite bit) integer nearest x/p (in half way 40 * case choose the even one). 41 * Method : 42 * Based on fmod() return x-[x/p]chopped*p exactly. 43 */ 44 45 #include "libm.h" 46 47 static const double zero = 0.0, half = 0.5; 48 49 double 50 remainder(double x, double p) 51 { 52 double halfp; 53 int ix, hx, hp; 54 55 ix = ((int *)&x)[HIWORD]; 56 hx = ix & ~0x80000000; 57 hp = ((int *)&p)[HIWORD] & ~0x80000000; 58 59 if (hp > 0x7ff00000 || (hp == 0x7ff00000 && ((int *)&p)[LOWORD] != 0)) 60 return (x * p); 61 62 if (hx > 0x7ff00000 || (hx == 0x7ff00000 && ((int *)&x)[LOWORD] != 0)) 63 return (x * p); 64 65 if ((hp | ((int *)&p)[LOWORD]) == 0 || hx == 0x7ff00000) 66 return (_SVID_libm_err(x, p, 28)); 67 68 p = fabs(p); 69 70 if (hp < 0x7fe00000) 71 x = fmod(x, p + p); 72 73 x = fabs(x); 74 75 if (hp < 0x00200000) { 76 if (x + x > p) { 77 if (x == p) /* avoid x-x=-0 in RM mode */ 78 return ((ix < 0) ? -zero : zero); 79 80 x -= p; 81 82 if (x + x >= p) 83 x -= p; 84 } 85 } else { 86 halfp = half * p; 87 88 if (x > halfp) { 89 if (x == p) /* avoid x-x=-0 in RM mode */ 90 return ((ix < 0) ? -zero : zero); 91 92 x -= p; 93 94 if (x >= halfp) 95 x -= p; 96 } 97 } 98 99 return ((ix < 0) ? -x : x); 100 }