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