Home | History | Annotate | Line # | Download | only in gen
t_fpclassify.c revision 1.1
      1 /* $NetBSD: t_fpclassify.c,v 1.1 2011/09/19 05:25:50 jruoho Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <atf-c.h>
     30 
     31 #include <float.h>
     32 #include <math.h>
     33 #include <stdio.h>
     34 #include <string.h>
     35 
     36 #if defined(__vax__)
     37 
     38 ATF_TC(no_test);
     39 ATF_TC_HEAD(no_test, tc)
     40 {
     41 	atf_tc_set_md_var(tc, "descr", "Dummy test");
     42 }
     43 
     44 ATF_TC_BODY(no_test,tc)
     45 {
     46 	atf_tc_skip("Test not available on this architecture");
     47 }
     48 
     49 #else /* defined(__vax__) */
     50 
     51 ATF_TC(fpclassify_float);
     52 ATF_TC_HEAD(fpclassify_float, tc)
     53 {
     54 
     55 	atf_tc_set_md_var(tc, "descr", "Test float operations");
     56 }
     57 
     58 ATF_TC_BODY(fpclassify_float, tc)
     59 {
     60 	float d0, d1, d2, f, ip;
     61 	int e, i;
     62 
     63 	d0 = FLT_MIN;
     64 	ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
     65 	f = frexpf(d0, &e);
     66 	ATF_REQUIRE_EQ(e, FLT_MIN_EXP);
     67 	ATF_REQUIRE_EQ(f, 0.5);
     68 	d1 = d0;
     69 
     70 	/* shift a "1" bit through the mantissa (skip the implicit bit) */
     71 	for (i = 1; i < FLT_MANT_DIG; i++) {
     72 		d1 /= 2;
     73 		ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
     74 		ATF_REQUIRE(d1 > 0 && d1 < d0);
     75 
     76 		d2 = ldexpf(d0, -i);
     77 		ATF_REQUIRE_EQ(d2, d1);
     78 
     79 		d2 = modff(d1, &ip);
     80 		ATF_REQUIRE_EQ(d2, d1);
     81 		ATF_REQUIRE_EQ(ip, 0);
     82 
     83 		f = frexpf(d1, &e);
     84 		ATF_REQUIRE_EQ(e, FLT_MIN_EXP - i);
     85 		ATF_REQUIRE_EQ(f, 0.5);
     86 	}
     87 
     88 	d1 /= 2;
     89 	ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
     90 	f = frexpf(d1, &e);
     91 	ATF_REQUIRE_EQ(e, 0);
     92 	ATF_REQUIRE_EQ(f, 0);
     93 }
     94 
     95 ATF_TC(fpclassify_double);
     96 ATF_TC_HEAD(fpclassify_double, tc)
     97 {
     98 
     99 	atf_tc_set_md_var(tc, "descr", "Test double operations");
    100 }
    101 
    102 ATF_TC_BODY(fpclassify_double, tc)
    103 {
    104 	double d0, d1, d2, f, ip;
    105 	int e, i;
    106 
    107 	d0 = DBL_MIN;
    108 	ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
    109 	f = frexp(d0, &e);
    110 	ATF_REQUIRE_EQ(e, DBL_MIN_EXP);
    111 	ATF_REQUIRE_EQ(f, 0.5);
    112 	d1 = d0;
    113 
    114 	/* shift a "1" bit through the mantissa (skip the implicit bit) */
    115 	for (i = 1; i < DBL_MANT_DIG; i++) {
    116 		d1 /= 2;
    117 		ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
    118 		ATF_REQUIRE(d1 > 0 && d1 < d0);
    119 
    120 		d2 = ldexp(d0, -i);
    121 		ATF_REQUIRE_EQ(d2, d1);
    122 
    123 		d2 = modf(d1, &ip);
    124 		ATF_REQUIRE_EQ(d2, d1);
    125 		ATF_REQUIRE_EQ(ip, 0);
    126 
    127 		f = frexp(d1, &e);
    128 		ATF_REQUIRE_EQ(e, DBL_MIN_EXP - i);
    129 		ATF_REQUIRE_EQ(f, 0.5);
    130 	}
    131 
    132 	d1 /= 2;
    133 	ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
    134 	f = frexp(d1, &e);
    135 	ATF_REQUIRE_EQ(e, 0);
    136 	ATF_REQUIRE_EQ(f, 0);
    137 }
    138 
    139 /*
    140  * XXX NetBSD doesn't have long-double flavors of frexp, ldexp, and modf,
    141  * XXX so this test is disabled.
    142  */
    143 
    144 #ifdef TEST_LONG_DOUBLE
    145 
    146 ATF_TC(fpclassify_long_double);
    147 ATF_TC_HEAD(fpclassify_long_double, tc)
    148 {
    149 
    150 	atf_tc_set_md_var(tc, "descr", "Test long double operations");
    151 }
    152 
    153 ATF_TC_BODY(fpclassify_long_double, tc)
    154 {
    155 	long double d0, d1, d2, f, ip;
    156 	int e, i;
    157 
    158 	d0 = LDBL_MIN;
    159 	ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
    160 	f = frexpl(d0, &e);
    161 	ATF_REQUIRE_EQ(e, LDBL_MIN_EXP);
    162 	ATF_REQUIRE_EQ(f, 0.5);
    163 	d1 = d0;
    164 
    165 	/* shift a "1" bit through the mantissa (skip the implicit bit) */
    166 	for (i = 1; i < LDBL_MANT_DIG; i++) {
    167 		d1 /= 2;
    168 		ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
    169 		ATF_REQUIRE(d1 > 0 && d1 < d0);
    170 
    171 		d2 = ldexpl(d0, -i);
    172 		ATF_REQUIRE_EQ(d2, d1);
    173 
    174 		d2 = modfl(d1, &ip);
    175 		ATF_REQUIRE_EQ(d2, d1);
    176 		ATF_REQUIRE_EQ(ip, 0);
    177 
    178 		f = frexpl(d1, &e);
    179 		ATF_REQUIRE_EQ(e, LDBL_MIN_EXP - i);
    180 		ATF_REQUIRE_EQ(f, 0.5);
    181 	}
    182 
    183 	d1 /= 2;
    184 	ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
    185 	f = frexpl(d1, &e);
    186 	ATF_REQUIRE_EQ(e, 0);
    187 	ATF_REQUIRE_EQ(f, 0);
    188 }
    189 #endif /* TEST_LONG_DOUBLE */
    190 #endif /* defined(__vax__) */
    191 
    192 ATF_TP_ADD_TCS(tp)
    193 {
    194 
    195 #if defined(__vax__)
    196 	ATF_TP_ADD_TC(tp, no_test);
    197 #else
    198 	ATF_TP_ADD_TC(tp, fpclassify_float);
    199 	ATF_TP_ADD_TC(tp, fpclassify_double);
    200 #ifdef TEST_LONG_DOUBLE
    201 	ATF_TP_ADD_TC(tp, fpclassify_long_double);
    202 #endif /* TEST_LONG_DOUBLE */
    203 #endif
    204 
    205 	return atf_no_error();
    206 }
    207