1 1.8 riastrad /* $NetBSD: t_fpclassify.c,v 1.8 2025/04/08 00:29:09 riastradh Exp $ */ 2 1.1 jruoho 3 1.1 jruoho /*- 4 1.1 jruoho * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 1.1 jruoho * All rights reserved. 6 1.1 jruoho * 7 1.1 jruoho * Redistribution and use in source and binary forms, with or without 8 1.1 jruoho * modification, are permitted provided that the following conditions 9 1.1 jruoho * are met: 10 1.1 jruoho * 1. Redistributions of source code must retain the above copyright 11 1.1 jruoho * notice, this list of conditions and the following disclaimer. 12 1.1 jruoho * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 jruoho * notice, this list of conditions and the following disclaimer in the 14 1.1 jruoho * documentation and/or other materials provided with the distribution. 15 1.1 jruoho * 16 1.1 jruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.1 jruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 jruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 jruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.1 jruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 jruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 jruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 jruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 jruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 jruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 jruoho * POSSIBILITY OF SUCH DAMAGE. 27 1.1 jruoho */ 28 1.1 jruoho 29 1.1 jruoho #include <atf-c.h> 30 1.1 jruoho 31 1.1 jruoho #include <float.h> 32 1.1 jruoho #include <math.h> 33 1.1 jruoho #include <stdio.h> 34 1.1 jruoho #include <string.h> 35 1.1 jruoho 36 1.1 jruoho ATF_TC(fpclassify_float); 37 1.1 jruoho ATF_TC_HEAD(fpclassify_float, tc) 38 1.1 jruoho { 39 1.1 jruoho 40 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test float operations"); 41 1.1 jruoho } 42 1.1 jruoho 43 1.1 jruoho ATF_TC_BODY(fpclassify_float, tc) 44 1.1 jruoho { 45 1.8 riastrad float d0, d1, f; 46 1.8 riastrad int e; 47 1.1 jruoho 48 1.1 jruoho d0 = FLT_MIN; 49 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d0), FP_NORMAL, 50 1.5 riastrad "fpclassify(%a)=%d FP_NORMAL=%d", 51 1.5 riastrad d0, fpclassify(d0), FP_NORMAL); 52 1.1 jruoho f = frexpf(d0, &e); 53 1.5 riastrad ATF_CHECK_EQ_MSG(e, FLT_MIN_EXP, 54 1.5 riastrad "frexpf(%a) returned normalized %a, exponent %d;" 55 1.5 riastrad " expected normalized %a, exponent %d", 56 1.5 riastrad d0, f, e, 0.5, FLT_MIN_EXP); 57 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0.5, 58 1.5 riastrad "frexpf(%a) returned normalized %a, exponent %d;" 59 1.5 riastrad " expected normalized %a, exponent %d", 60 1.5 riastrad d0, f, e, 0.5, FLT_MIN_EXP); 61 1.1 jruoho d1 = d0; 62 1.1 jruoho 63 1.7 riastrad #if __FLT_HAS_DENORM__ 64 1.1 jruoho /* shift a "1" bit through the mantissa (skip the implicit bit) */ 65 1.8 riastrad for (int i = 1; i < FLT_MANT_DIG; i++) { 66 1.8 riastrad float d2, ip; 67 1.8 riastrad 68 1.1 jruoho d1 /= 2; 69 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d1), FP_SUBNORMAL, 70 1.5 riastrad "[%d] fpclassify(%a)=%d FP_SUBNORMAL=%d", 71 1.5 riastrad i, d1, fpclassify(d1), FP_SUBNORMAL); 72 1.5 riastrad ATF_CHECK_MSG(d1 > 0 && d1 < d0, 73 1.5 riastrad "[%d] d1=%a d0=%a", i, d1, d0); 74 1.1 jruoho 75 1.1 jruoho d2 = ldexpf(d0, -i); 76 1.5 riastrad ATF_CHECK_EQ_MSG(d2, d1, "[%d] ldexpf(%a, -%d)=%a != %a", 77 1.5 riastrad i, d0, i, d2, d1); 78 1.1 jruoho 79 1.1 jruoho d2 = modff(d1, &ip); 80 1.5 riastrad ATF_CHECK_EQ_MSG(d2, d1, 81 1.5 riastrad "[%d] modff(%a) returned int %a, frac %a;" 82 1.5 riastrad " expected int %a, frac %a", 83 1.5 riastrad i, d1, ip, d2, 0., d1); 84 1.5 riastrad ATF_CHECK_EQ_MSG(ip, 0, 85 1.5 riastrad "[%d] modff(%a) returned int %a, frac %a;" 86 1.5 riastrad " expected int %a, frac %a", 87 1.5 riastrad i, d1, ip, d2, 0., d1); 88 1.1 jruoho 89 1.1 jruoho f = frexpf(d1, &e); 90 1.5 riastrad ATF_CHECK_EQ_MSG(e, FLT_MIN_EXP - i, 91 1.5 riastrad "[%d] frexpf(%a) returned normalized %a, exponent %d;" 92 1.5 riastrad " expected normalized %a, exponent %d", 93 1.5 riastrad i, d1, f, e, 0.5, FLT_MIN_EXP - i); 94 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0.5, 95 1.5 riastrad "[%d] frexpf(%a) returned normalized %a, exponent %d;" 96 1.5 riastrad " expected normalized %a, exponent %d", 97 1.5 riastrad i, d1, f, e, 0.5, FLT_MIN_EXP - i); 98 1.1 jruoho } 99 1.6 riastrad #endif 100 1.1 jruoho 101 1.1 jruoho d1 /= 2; 102 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d1), FP_ZERO, 103 1.5 riastrad "fpclassify(%a)=%d FP_ZERO=%d", 104 1.5 riastrad d1, fpclassify(d1), FP_ZERO); 105 1.1 jruoho f = frexpf(d1, &e); 106 1.5 riastrad ATF_CHECK_EQ_MSG(e, 0, 107 1.5 riastrad "frexpf(%a) returned normalized %a, exponent %d;" 108 1.5 riastrad " expected normalized %a, exponent %d", 109 1.5 riastrad d1, f, e, 0., 0); 110 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0, 111 1.5 riastrad "frexpf(%a) returned normalized %a, exponent %d;" 112 1.5 riastrad " expected normalized %a, exponent %d", 113 1.5 riastrad d1, f, e, 0., 0); 114 1.1 jruoho } 115 1.1 jruoho 116 1.1 jruoho ATF_TC(fpclassify_double); 117 1.1 jruoho ATF_TC_HEAD(fpclassify_double, tc) 118 1.1 jruoho { 119 1.1 jruoho 120 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test double operations"); 121 1.1 jruoho } 122 1.1 jruoho 123 1.1 jruoho ATF_TC_BODY(fpclassify_double, tc) 124 1.1 jruoho { 125 1.8 riastrad double d0, d1, f; 126 1.8 riastrad int e; 127 1.1 jruoho 128 1.1 jruoho d0 = DBL_MIN; 129 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d0), FP_NORMAL, 130 1.5 riastrad "fpclassify(%a)=%d FP_NORMAL=%d", 131 1.5 riastrad d0, fpclassify(d0), FP_NORMAL); 132 1.1 jruoho f = frexp(d0, &e); 133 1.5 riastrad ATF_CHECK_EQ_MSG(e, DBL_MIN_EXP, 134 1.5 riastrad "frexp(%a) returned normalized %a, exponent %d;" 135 1.5 riastrad " expected normalized %a, exponent %d", 136 1.5 riastrad d0, f, e, 0.5, DBL_MIN_EXP); 137 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0.5, 138 1.5 riastrad "frexp(%a) returned normalized %a, exponent %d;" 139 1.5 riastrad " expected normalized %a, exponent %d", 140 1.5 riastrad d0, f, e, 0.5, DBL_MIN_EXP); 141 1.1 jruoho d1 = d0; 142 1.1 jruoho 143 1.7 riastrad #if __DBL_HAS_DENORM__ 144 1.1 jruoho /* shift a "1" bit through the mantissa (skip the implicit bit) */ 145 1.8 riastrad for (int i = 1; i < DBL_MANT_DIG; i++) { 146 1.8 riastrad double d2, ip; 147 1.8 riastrad 148 1.1 jruoho d1 /= 2; 149 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d1), FP_SUBNORMAL, 150 1.5 riastrad "[%d] fpclassify(%a)=%d FP_SUBNORMAL=%d", 151 1.5 riastrad i, d1, fpclassify(d1), FP_SUBNORMAL); 152 1.5 riastrad ATF_CHECK_MSG(d1 > 0 && d1 < d0, 153 1.5 riastrad "[%d] d1=%a d0=%a", i, d1, d0); 154 1.1 jruoho 155 1.1 jruoho d2 = ldexp(d0, -i); 156 1.5 riastrad ATF_CHECK_EQ_MSG(d2, d1, "[%d] ldexp(%a, -%d)=%a != %a", 157 1.5 riastrad i, d0, i, d2, d1); 158 1.1 jruoho 159 1.1 jruoho d2 = modf(d1, &ip); 160 1.5 riastrad ATF_CHECK_EQ_MSG(d2, d1, 161 1.5 riastrad "[%d] modf(%a) returned int %a, frac %a;" 162 1.5 riastrad " expected int %a, frac %a", 163 1.5 riastrad i, d1, ip, d2, 0., d1); 164 1.5 riastrad ATF_CHECK_EQ_MSG(ip, 0, 165 1.5 riastrad "[%d] modf(%a) returned int %a, frac %a;" 166 1.5 riastrad " expected int %a, frac %a", 167 1.5 riastrad i, d1, ip, d2, 0., d1); 168 1.1 jruoho 169 1.1 jruoho f = frexp(d1, &e); 170 1.5 riastrad ATF_CHECK_EQ_MSG(e, DBL_MIN_EXP - i, 171 1.5 riastrad "[%d] frexp(%a) returned normalized %a, exponent %d;" 172 1.5 riastrad " expected normalized %a, exponent %d", 173 1.5 riastrad i, d1, f, e, 0.5, DBL_MIN_EXP - i); 174 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0.5, 175 1.5 riastrad "[%d] frexp(%a) returned normalized %a, exponent %d;" 176 1.5 riastrad " expected normalized %a, exponent %d", 177 1.5 riastrad i, d1, f, e, 0.5, DBL_MIN_EXP - i); 178 1.1 jruoho } 179 1.6 riastrad #endif 180 1.1 jruoho 181 1.1 jruoho d1 /= 2; 182 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d1), FP_ZERO, 183 1.5 riastrad "fpclassify(%a)=%d FP_ZERO=%d", 184 1.5 riastrad d1, fpclassify(d1), FP_ZERO); 185 1.1 jruoho f = frexp(d1, &e); 186 1.5 riastrad ATF_CHECK_EQ_MSG(e, 0, 187 1.5 riastrad "frexp(%a) returned normalized %a, exponent %d;" 188 1.5 riastrad " expected normalized %a, exponent %d", 189 1.5 riastrad d1, f, e, 0., 0); 190 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0, 191 1.5 riastrad "frexp(%a) returned normalized %a, exponent %d;" 192 1.5 riastrad " expected normalized %a, exponent %d", 193 1.5 riastrad d1, f, e, 0., 0); 194 1.1 jruoho } 195 1.1 jruoho 196 1.1 jruoho ATF_TC(fpclassify_long_double); 197 1.1 jruoho ATF_TC_HEAD(fpclassify_long_double, tc) 198 1.1 jruoho { 199 1.1 jruoho 200 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test long double operations"); 201 1.1 jruoho } 202 1.1 jruoho 203 1.1 jruoho ATF_TC_BODY(fpclassify_long_double, tc) 204 1.1 jruoho { 205 1.8 riastrad long double d0, d1, f; 206 1.8 riastrad int e; 207 1.1 jruoho 208 1.1 jruoho d0 = LDBL_MIN; 209 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d0), FP_NORMAL, 210 1.5 riastrad "fpclassify(%La)=%d FP_NORMAL=%d", 211 1.5 riastrad d0, fpclassify(d0), FP_NORMAL); 212 1.1 jruoho f = frexpl(d0, &e); 213 1.5 riastrad ATF_CHECK_EQ_MSG(e, LDBL_MIN_EXP, 214 1.5 riastrad "frexpl(%La) returned normalized %La, exponent %d;" 215 1.5 riastrad " expected normalized %La, exponent %d", 216 1.5 riastrad d0, f, e, 0.5L, LDBL_MIN_EXP); 217 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0.5, 218 1.5 riastrad "frexpl(%La) returned normalized %La, exponent %d;" 219 1.5 riastrad " expected normalized %La, exponent %d", 220 1.5 riastrad d0, f, e, 0.5L, LDBL_MIN_EXP); 221 1.1 jruoho d1 = d0; 222 1.1 jruoho 223 1.7 riastrad #if __LDBL_HAS_DENORM__ 224 1.1 jruoho /* shift a "1" bit through the mantissa (skip the implicit bit) */ 225 1.8 riastrad for (int i = 1; i < LDBL_MANT_DIG; i++) { 226 1.8 riastrad long double d2, ip; 227 1.8 riastrad 228 1.1 jruoho d1 /= 2; 229 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d1), FP_SUBNORMAL, 230 1.5 riastrad "[%d] fpclassify(%La)=%d FP_SUBNORMAL=%d", 231 1.5 riastrad i, d1, fpclassify(d1), FP_SUBNORMAL); 232 1.5 riastrad ATF_CHECK_MSG(d1 > 0 && d1 < d0, 233 1.5 riastrad "[%d] d1=%La d0=%La", i, d1, d0); 234 1.1 jruoho 235 1.1 jruoho d2 = ldexpl(d0, -i); 236 1.5 riastrad ATF_CHECK_EQ_MSG(d2, d1, "[%d] ldexpl(%La, -%d)=%La != %La", 237 1.5 riastrad i, d0, i, d2, d1); 238 1.1 jruoho 239 1.1 jruoho d2 = modfl(d1, &ip); 240 1.5 riastrad ATF_CHECK_EQ_MSG(d2, d1, 241 1.5 riastrad "[%d] modfl(%La) returned int %La, frac %La;" 242 1.5 riastrad " expected int %La, frac %La", 243 1.5 riastrad i, d1, ip, d2, 0.L, d1); 244 1.5 riastrad ATF_CHECK_EQ_MSG(ip, 0, 245 1.5 riastrad "[%d] modfl(%La) returned int %La, frac %La;" 246 1.5 riastrad " expected int %La, frac %La", 247 1.5 riastrad i, d1, ip, d2, 0.L, d1); 248 1.1 jruoho 249 1.1 jruoho f = frexpl(d1, &e); 250 1.5 riastrad ATF_CHECK_EQ_MSG(e, LDBL_MIN_EXP - i, 251 1.5 riastrad "[%d] frexpl(%La) returned normalized %La, exponent %d;" 252 1.5 riastrad " expected normalized %La, exponent %d", 253 1.5 riastrad i, d1, f, e, 0.5L, LDBL_MIN_EXP - i); 254 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0.5, 255 1.5 riastrad "[%d] frexpl(%La) returned normalized %La, exponent %d;" 256 1.5 riastrad " expected normalized %La, exponent %d", 257 1.5 riastrad i, d1, f, e, 0.5L, LDBL_MIN_EXP - i); 258 1.1 jruoho } 259 1.6 riastrad #endif 260 1.1 jruoho 261 1.1 jruoho d1 /= 2; 262 1.5 riastrad ATF_CHECK_EQ_MSG(fpclassify(d1), FP_ZERO, 263 1.5 riastrad "fpclassify(%La)=%d FP_ZERO=%d", 264 1.5 riastrad d1, fpclassify(d1), FP_ZERO); 265 1.1 jruoho f = frexpl(d1, &e); 266 1.5 riastrad ATF_CHECK_EQ_MSG(e, 0, 267 1.5 riastrad "frexpl(%La) returned normalized %La, exponent %d;" 268 1.5 riastrad " expected normalized %La, exponent %d", 269 1.5 riastrad d1, f, e, 0.L, 0); 270 1.5 riastrad ATF_CHECK_EQ_MSG(f, 0, 271 1.5 riastrad "frexpl(%La) returned normalized %La, exponent %d;" 272 1.5 riastrad " expected normalized %La, exponent %d", 273 1.5 riastrad d1, f, e, 0.L, 0); 274 1.1 jruoho } 275 1.4 riastrad 276 1.1 jruoho ATF_TP_ADD_TCS(tp) 277 1.1 jruoho { 278 1.1 jruoho 279 1.1 jruoho ATF_TP_ADD_TC(tp, fpclassify_float); 280 1.1 jruoho ATF_TP_ADD_TC(tp, fpclassify_double); 281 1.1 jruoho ATF_TP_ADD_TC(tp, fpclassify_long_double); 282 1.1 jruoho 283 1.1 jruoho return atf_no_error(); 284 1.1 jruoho } 285