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 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 23 */ 24 /* 25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #pragma weak aintl = __aintl 30 #pragma weak anintl = __anintl 31 #pragma weak irintl = __irintl 32 #pragma weak nintl = __nintl 33 34 /* 35 * aintl(x) return x chopped to integral value 36 * anintl(x) return sign(x)*(|x|+0.5) chopped to integral value 37 * irintl(x) return rint(x) in integer format 38 * nintl(x) return anint(x) in integer format 39 * 40 * NOTE: aintl(x), anintl(x), ceill(x), floorl(x), and rintl(x) return result 41 * with the same sign as x's, including 0.0. 42 */ 43 44 #include "libm.h" 45 #include "longdouble.h" 46 47 extern enum fp_direction_type __swapRD(enum fp_direction_type); 48 49 static const long double qone = 1.0L, qhalf = 0.5L, qmhalf = -0.5L; 50 51 long double 52 aintl(long double x) { 53 long double t, w; 54 55 if (!finitel(x)) 56 return (x + x); 57 w = fabsl(x); 58 t = rintl(w); 59 if (t <= w) 60 return (copysignl(t, x)); /* NaN or already aint(|x|) */ 61 else /* |t|>|x| case */ 62 return (copysignl(t - qone, x)); /* |t-1|*sign(x) */ 63 } 64 65 long double 66 anintl(long double x) { 67 long double t, w, z; 68 69 if (!finitel(x)) 70 return (x + x); 71 w = fabsl(x); 72 t = rintl(w); 73 if (t == w) 74 return (copysignl(t, x)); 75 z = t - w; 76 if (z > qhalf) 77 t = t - qone; 78 else if (z <= qmhalf) 79 t = t + qone; 80 return (copysignl(t, x)); 81 } 82 83 int 84 irintl(long double x) { 85 enum fp_direction_type rd; 86 87 rd = __swapRD(fp_nearest); 88 (void) __swapRD(rd); /* restore Rounding Direction */ 89 switch (rd) { 90 case fp_nearest: 91 if (x < 2147483647.5L && x >= -2147483648.5L) 92 return ((int)rintl(x)); 93 break; 94 case fp_tozero: 95 if (x < 2147483648.0L && x > -2147483649.0L) 96 return ((int)rintl(x)); 97 break; 98 case fp_positive: 99 if (x <= 2147483647.0L && x > -2147483649.0L) 100 return ((int)rintl(x)); 101 break; 102 case fp_negative: 103 if (x < 2147483648.0L && x >= -2147483648.0L) 104 return ((int)rintl(x)); 105 break; 106 } 107 return ((int)copysignl(1.0e100L, x)); 108 } 109 110 int 111 nintl(long double x) { 112 if ((x < 2147483647.5L) && (x > -2147483648.5L)) 113 return ((int)anintl(x)); 114 else 115 return ((int)copysignl(1.0e100L, x)); 116 }