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