Module Name: src Committed By: joerg Date: Tue Nov 12 16:48:39 UTC 2013
Modified Files: src/distrib/sets/lists/comp: mi src/distrib/sets/lists/debug: mi src/distrib/sets/lists/tests: mi src/lib/libm: Makefile src/lib/libm/man: fmod.3 src/lib/libm/src: math_private.h namespace.h w_fmod.c src/tests/lib/libm: Makefile Added Files: src/lib/libm/src: e_fmodl.c w_fmodl.c src/tests/lib/libm: t_fmod.c Log Message: Initial version of fmodl from FreeBSD. Basic test case for the fmod family. To generate a diff of this commit: cvs rdiff -u -r1.1856 -r1.1857 src/distrib/sets/lists/comp/mi cvs rdiff -u -r1.39 -r1.40 src/distrib/sets/lists/debug/mi cvs rdiff -u -r1.549 -r1.550 src/distrib/sets/lists/tests/mi cvs rdiff -u -r1.145 -r1.146 src/lib/libm/Makefile cvs rdiff -u -r1.11 -r1.12 src/lib/libm/man/fmod.3 cvs rdiff -u -r0 -r1.1 src/lib/libm/src/e_fmodl.c src/lib/libm/src/w_fmodl.c cvs rdiff -u -r1.18 -r1.19 src/lib/libm/src/math_private.h cvs rdiff -u -r1.6 -r1.7 src/lib/libm/src/namespace.h cvs rdiff -u -r1.9 -r1.10 src/lib/libm/src/w_fmod.c cvs rdiff -u -r1.19 -r1.20 src/tests/lib/libm/Makefile cvs rdiff -u -r0 -r1.1 src/tests/lib/libm/t_fmod.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/comp/mi diff -u src/distrib/sets/lists/comp/mi:1.1856 src/distrib/sets/lists/comp/mi:1.1857 --- src/distrib/sets/lists/comp/mi:1.1856 Tue Nov 12 16:39:39 2013 +++ src/distrib/sets/lists/comp/mi Tue Nov 12 16:48:39 2013 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1856 2013/11/12 16:39:39 joerg Exp $ +# $NetBSD: mi,v 1.1857 2013/11/12 16:48:39 joerg Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -6282,6 +6282,7 @@ ./usr/share/man/cat3/fminl.0 comp-c-catman .cat ./usr/share/man/cat3/fmod.0 comp-c-catman .cat ./usr/share/man/cat3/fmodf.0 comp-c-catman .cat +./usr/share/man/cat3/fmodl.0 comp-c-catman .cat ./usr/share/man/cat3/fmtcheck.0 comp-c-catman .cat ./usr/share/man/cat3/fmtmsg.0 comp-c-catman .cat ./usr/share/man/cat3/fnmatch.0 comp-c-catman .cat @@ -12838,6 +12839,7 @@ ./usr/share/man/html3/fminl.html comp-c-htmlman html ./usr/share/man/html3/fmod.html comp-c-htmlman html ./usr/share/man/html3/fmodf.html comp-c-htmlman html +./usr/share/man/html3/fmodl.html comp-c-htmlman html ./usr/share/man/html3/fmtcheck.html comp-c-htmlman html ./usr/share/man/html3/fmtmsg.html comp-c-htmlman html ./usr/share/man/html3/fnmatch.html comp-c-htmlman html @@ -19308,6 +19310,7 @@ ./usr/share/man/man3/fminl.3 comp-c-man .man ./usr/share/man/man3/fmod.3 comp-c-man .man ./usr/share/man/man3/fmodf.3 comp-c-man .man +./usr/share/man/man3/fmodl.3 comp-c-man .man ./usr/share/man/man3/fmtcheck.3 comp-c-man .man ./usr/share/man/man3/fmtmsg.3 comp-c-man .man ./usr/share/man/man3/fnmatch.3 comp-c-man .man Index: src/distrib/sets/lists/debug/mi diff -u src/distrib/sets/lists/debug/mi:1.39 src/distrib/sets/lists/debug/mi:1.40 --- src/distrib/sets/lists/debug/mi:1.39 Mon Nov 11 11:10:45 2013 +++ src/distrib/sets/lists/debug/mi Tue Nov 12 16:48:39 2013 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.39 2013/11/11 11:10:45 joerg Exp $ +# $NetBSD: mi,v 1.40 2013/11/12 16:48:39 joerg Exp $ ./etc/mtree/set.debug comp-sys-root ./usr/lib/i18n/libBIG5_g.a comp-c-debuglib debuglib @@ -1975,6 +1975,7 @@ ./usr/libdata/debug/usr/tests/lib/libm/t_erf.debug tests-lib-debug debug,atf ./usr/libdata/debug/usr/tests/lib/libm/t_exp.debug tests-lib-debug debug,atf ./usr/libdata/debug/usr/tests/lib/libm/t_floor.debug tests-obsolete obsolete +./usr/libdata/debug/usr/tests/lib/libm/t_fmod.debug tests-lib-debug debug,atf ./usr/libdata/debug/usr/tests/lib/libm/t_infinity.debug tests-lib-debug debug,atf ./usr/libdata/debug/usr/tests/lib/libm/t_ldexp.debug tests-lib-debug debug,atf ./usr/libdata/debug/usr/tests/lib/libm/t_libm.debug tests-obsolete obsolete Index: src/distrib/sets/lists/tests/mi diff -u src/distrib/sets/lists/tests/mi:1.549 src/distrib/sets/lists/tests/mi:1.550 --- src/distrib/sets/lists/tests/mi:1.549 Tue Nov 12 12:22:33 2013 +++ src/distrib/sets/lists/tests/mi Tue Nov 12 16:48:39 2013 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.549 2013/11/12 12:22:33 kefren Exp $ +# $NetBSD: mi,v 1.550 2013/11/12 16:48:39 joerg Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -2353,6 +2353,7 @@ ./usr/tests/lib/libm/t_erf tests-lib-tests atf ./usr/tests/lib/libm/t_exp tests-lib-tests atf ./usr/tests/lib/libm/t_floor tests-obsolete obsolete +./usr/tests/lib/libm/t_fmod tests-lib-tests atf ./usr/tests/lib/libm/t_infinity tests-lib-tests atf ./usr/tests/lib/libm/t_ldexp tests-lib-tests atf ./usr/tests/lib/libm/t_libm tests-obsolete obsolete Index: src/lib/libm/Makefile diff -u src/lib/libm/Makefile:1.145 src/lib/libm/Makefile:1.146 --- src/lib/libm/Makefile:1.145 Tue Nov 12 00:10:29 2013 +++ src/lib/libm/Makefile Tue Nov 12 16:48:39 2013 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.145 2013/11/12 00:10:29 joerg Exp $ +# $NetBSD: Makefile,v 1.146 2013/11/12 16:48:39 joerg Exp $ # # @(#)Makefile 5.1beta 93/09/24 # @@ -151,7 +151,8 @@ LIB= m COMMON_SRCS+= b_exp.c b_log.c b_tgamma.c \ e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \ e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \ - e_expf.c e_fmod.c e_fmodf.c e_hypot.c e_hypotf.c e_j0.c e_j0f.c \ + e_expf.c e_fmod.c e_fmodf.c e_fmodl.c e_hypot.c e_hypotf.c \ + e_j0.c e_j0f.c \ e_j1.c e_j1f.c e_jn.c e_jnf.c e_lgamma_r.c e_lgammaf_r.c e_log.c \ e_log2.c e_log10.c e_log10f.c e_log2f.c e_logf.c e_pow.c e_powf.c \ e_rem_pio2.c e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c \ @@ -174,8 +175,9 @@ COMMON_SRCS+= b_exp.c b_log.c b_tgamma.c s_sinf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tgammaf.c s_trunc.c s_truncf.c \ w_acos.c w_acosf.c w_acosh.c w_acoshf.c w_asin.c w_asinf.c w_atan2.c \ w_atan2f.c w_atanh.c w_atanhf.c w_cosh.c w_coshf.c \ - w_drem.c w_dremf.c w_exp.c w_expf.c w_fmod.c w_fmodf.c w_gamma.c \ - w_gamma_r.c w_gammaf.c w_gammaf_r.c w_hypot.c w_hypotf.c w_j0.c \ + w_drem.c w_dremf.c w_exp.c w_expf.c w_fmod.c w_fmodf.c w_fmodl.c \ + w_gamma.c w_gamma_r.c w_gammaf.c w_gammaf_r.c w_hypot.c w_hypotf.c \ + w_j0.c \ w_j0f.c w_j1.c w_j1f.c w_jn.c w_jnf.c w_lgamma.c w_lgamma_r.c \ w_lgammaf.c w_lgammaf_r.c w_log.c w_log10.c w_log10f.c w_log2.c \ w_log2f.c w_logf.c \ @@ -284,7 +286,8 @@ MLINKS+=log.3 logf.3 \ MLINKS+=pow.3 powf.3 MLINKS+=fabs.3 fabsf.3 MLINKS+=finite.3 finitef.3 -MLINKS+=fmod.3 fmodf.3 +MLINKS+=fmod.3 fmodf.3 \ + fmod.3 fmodl.3 MLINKS+=hypot.3 hypotf.3 MLINKS+=ieee_test.3 logb.3 ieee_test.3 logbf.3 ieee_test.3 logbl.3 MLINKS+=ieee_test.3 scalb.3 ieee_test.3 scalbf.3 Index: src/lib/libm/man/fmod.3 diff -u src/lib/libm/man/fmod.3:1.11 src/lib/libm/man/fmod.3:1.12 --- src/lib/libm/man/fmod.3:1.11 Thu Aug 7 16:44:47 2003 +++ src/lib/libm/man/fmod.3 Tue Nov 12 16:48:39 2013 @@ -26,14 +26,15 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)fmod.3 5.1 (Berkeley) 5/2/91 -.\" $NetBSD: fmod.3,v 1.11 2003/08/07 16:44:47 agc Exp $ +.\" $NetBSD: fmod.3,v 1.12 2013/11/12 16:48:39 joerg Exp $ .\" -.Dd May 2, 1991 +.Dd November 12, 2013 .Dt FMOD 3 .Os .Sh NAME .Nm fmod , -.Nm fmodf +.Nm fmodf , +.Nm fmodl .Nd floating-point remainder function .Sh LIBRARY .Lb libm @@ -43,6 +44,8 @@ .Fn fmod "double x" "double y" .Ft float .Fn fmodf "float x" "float y" +.Ft long double +.Fn fmodl "long double x" "long double y" .Sh DESCRIPTION The .Fn fmod @@ -50,9 +53,10 @@ function computes the floating-point rem .Fa x Ns / Fa y . .Sh RETURN VALUES The -.Fn fmod +.Fn fmod , +.Fn fmodf , and -.Fn fmodf +.Fn fmodl functions return the value .Sm off .Fa x - Em i * Fa y , Index: src/lib/libm/src/math_private.h diff -u src/lib/libm/src/math_private.h:1.18 src/lib/libm/src/math_private.h:1.19 --- src/lib/libm/src/math_private.h:1.18 Mon Feb 11 01:29:58 2013 +++ src/lib/libm/src/math_private.h Tue Nov 12 16:48:39 2013 @@ -11,7 +11,7 @@ /* * from: @(#)fdlibm.h 5.1 93/09/24 - * $NetBSD: math_private.h,v 1.18 2013/02/11 01:29:58 christos Exp $ + * $NetBSD: math_private.h,v 1.19 2013/11/12 16:48:39 joerg Exp $ */ #ifndef _MATH_PRIVATE_H_ @@ -299,6 +299,9 @@ extern float __kernel_cosf __P((float,fl extern float __kernel_tanf __P((float,float,int)); extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*)); +/* ieee style elementary long double functions */ +extern long double __ieee754_fmodl(long double, long double); + /* * TRUNC() is a macro that sets the trailing 27 bits in the mantissa of an * IEEE double variable to zero. It must be expression-like for syntactic Index: src/lib/libm/src/namespace.h diff -u src/lib/libm/src/namespace.h:1.6 src/lib/libm/src/namespace.h:1.7 --- src/lib/libm/src/namespace.h:1.6 Mon Nov 11 23:57:34 2013 +++ src/lib/libm/src/namespace.h Tue Nov 12 16:48:39 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: namespace.h,v 1.6 2013/11/11 23:57:34 joerg Exp $ */ +/* $NetBSD: namespace.h,v 1.7 2013/11/12 16:48:39 joerg Exp $ */ #define atan2 _atan2 #define atan2f _atan2f @@ -49,3 +49,4 @@ #define ceill _ceill #define floorl _floorl #define roundl _roundl +#define fmodl _fmodl Index: src/lib/libm/src/w_fmod.c diff -u src/lib/libm/src/w_fmod.c:1.9 src/lib/libm/src/w_fmod.c:1.10 --- src/lib/libm/src/w_fmod.c:1.9 Sun May 26 22:02:00 2002 +++ src/lib/libm/src/w_fmod.c Tue Nov 12 16:48:39 2013 @@ -12,7 +12,7 @@ #include <sys/cdefs.h> #if defined(LIBM_SCCS) && !defined(lint) -__RCSID("$NetBSD: w_fmod.c,v 1.9 2002/05/26 22:02:00 wiz Exp $"); +__RCSID("$NetBSD: w_fmod.c,v 1.10 2013/11/12 16:48:39 joerg Exp $"); #endif /* @@ -22,6 +22,10 @@ __RCSID("$NetBSD: w_fmod.c,v 1.9 2002/05 #include "math.h" #include "math_private.h" +#ifndef __HAVE_LONG_DOUBLE +__strong_alias(_fmodl, fmod) +__weak_alias(fmodl, fmod) +#endif double fmod(double x, double y) /* wrapper fmod */ Index: src/tests/lib/libm/Makefile diff -u src/tests/lib/libm/Makefile:1.19 src/tests/lib/libm/Makefile:1.20 --- src/tests/lib/libm/Makefile:1.19 Mon Nov 11 11:10:45 2013 +++ src/tests/lib/libm/Makefile Tue Nov 12 16:48:39 2013 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.19 2013/11/11 11:10:45 joerg Exp $ +# $NetBSD: Makefile,v 1.20 2013/11/12 16:48:39 joerg Exp $ .include <bsd.own.mk> @@ -13,6 +13,7 @@ TESTS_C+= t_cos TESTS_C+= t_cosh TESTS_C+= t_erf TESTS_C+= t_exp +TESTS_C+= t_fmod TESTS_C+= t_infinity TESTS_C+= t_ldexp TESTS_C+= t_log Added files: Index: src/lib/libm/src/e_fmodl.c diff -u /dev/null src/lib/libm/src/e_fmodl.c:1.1 --- /dev/null Tue Nov 12 16:48:39 2013 +++ src/lib/libm/src/e_fmodl.c Tue Nov 12 16:48:39 2013 @@ -0,0 +1,157 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: e_fmodl.c,v 1.1 2013/11/12 16:48:39 joerg Exp $"); +#if 0 +__FBSDID("$FreeBSD: head/lib/msun/src/e_fmodl.c 181063 2008-07-31 20:09:47Z das $"); +#endif + +#include "namespace.h" + +#include <float.h> +#include <stdint.h> + +#include "math.h" +#include "math_private.h" +#include <machine/ieee.h> + +#ifdef __HAVE_LONG_DOUBLE + +#define BIAS (LDBL_MAX_EXP - 1) + +#if EXT_FRACLBITS > 32 +typedef uint64_t manl_t; +#else +typedef uint32_t manl_t; +#endif + +#if EXT_FRACHBITS > 32 +typedef uint64_t manh_t; +#else +typedef uint32_t manh_t; +#endif + +/* + * These macros add and remove an explicit integer bit in front of the + * fractional mantissa, if the architecture doesn't have such a bit by + * default already. + */ +#ifdef LDBL_IMPLICIT_NBIT +#define SET_NBIT(hx) ((hx) | (1ULL << EXT_FRACHBITS)) +#define HFRAC_BITS EXT_FRACHBITS +#else +#define SET_NBIT(hx) (hx) +#define HFRAC_BITS (EXT_FRACHBITS - 1) +#endif + +#define MANL_SHIFT (EXT_FRACLBITS - 1) + +static const long double one = 1.0, Zero[] = {0.0, -0.0,}; + +/* + * fmodl(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + * + * Assumptions: + * - The low part of the mantissa fits in a manl_t exactly. + * - The high part of the mantissa fits in an int64_t with enough room + * for an explicit integer bit in front of the fractional bits. + */ +long double +__ieee754_fmodl(long double x, long double y) +{ + union ieee_ext_u ux = { .extu_ld = x, }; + union ieee_ext_u uy = { .extu_ld = y, }; + int64_t hx,hz; /* We need a carry bit even if EXT_FRACHBITS is 32. */ + manh_t hy; + manl_t lx,ly,lz; + int ix,iy,n,sx; + + sx = ux.extu_sign; + + /* purge off exception values */ + if((uy.extu_exp|uy.extu_frach|uy.extu_fracl)==0 || /* y=0 */ + (ux.extu_exp == BIAS + LDBL_MAX_EXP) || /* or x not finite */ + (uy.extu_exp == BIAS + LDBL_MAX_EXP && + ((uy.extu_frach&~LDBL_NBIT)|uy.extu_fracl)!=0)) /* or y is NaN */ + return (x*y)/(x*y); + if(ux.extu_exp<=uy.extu_exp) { + if((ux.extu_exp<uy.extu_exp) || + (ux.extu_frach<=uy.extu_frach && + (ux.extu_frach<uy.extu_frach || + ux.extu_fracl<uy.extu_fracl))) { + return x; /* |x|<|y| return x or x-y */ + } + if(ux.extu_frach==uy.extu_frach && ux.extu_fracl==uy.extu_fracl) { + return Zero[sx]; /* |x|=|y| return x*0*/ + } + } + + /* determine ix = ilogb(x) */ + if(ux.extu_exp == 0) { /* subnormal x */ + ux.extu_ld *= 0x1.0p512; + ix = ux.extu_exp - (BIAS + 512); + } else { + ix = ux.extu_exp - BIAS; + } + + /* determine iy = ilogb(y) */ + if(uy.extu_exp == 0) { /* subnormal y */ + uy.extu_ld *= 0x1.0p512; + iy = uy.extu_exp - (BIAS + 512); + } else { + iy = uy.extu_exp - BIAS; + } + + /* set up {hx,lx}, {hy,ly} and align y to x */ + hx = SET_NBIT(ux.extu_frach); + hy = SET_NBIT(uy.extu_frach); + lx = ux.extu_fracl; + ly = uy.extu_fracl; + + /* fix point fmod */ + n = ix - iy; + + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz<0){hx = hx+hx+(lx>>MANL_SHIFT); lx = lx+lx;} + else { + if ((hz|lz)==0) /* return sign(x)*0 */ + return Zero[sx]; + hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz>=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[sx]; + while(hx<(1LL<<HFRAC_BITS)) { /* normalize x */ + hx = hx+hx+(lx>>MANL_SHIFT); lx = lx+lx; + iy -= 1; + } + ux.extu_frach = hx; /* The mantissa is truncated here if needed. */ + ux.extu_fracl = lx; + if (iy < LDBL_MIN_EXP) { + ux.extu_exp = iy + (BIAS + 512); + ux.extu_ld *= 0x1p-512; + } else { + ux.extu_exp = iy + BIAS; + } + x = ux.extu_ld * one; /* create necessary signal */ + return x; /* exact output */ +} + +#endif /* __HAVE_LONG_DOUBLE */ Index: src/lib/libm/src/w_fmodl.c diff -u /dev/null src/lib/libm/src/w_fmodl.c:1.1 --- /dev/null Tue Nov 12 16:48:39 2013 +++ src/lib/libm/src/w_fmodl.c Tue Nov 12 16:48:39 2013 @@ -0,0 +1,42 @@ +/* @(#)w_fmod.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: w_fmodl.c,v 1.1 2013/11/12 16:48:39 joerg Exp $"); + +/* + * wrapper fmodl(x,y) + */ +#include "namespace.h" + +#include "math.h" +#include "math_private.h" + +#ifdef __weak_alias +__weak_alias(fmodl, _fmodl) +#endif + +long double +fmodl(long double x, long double y) /* wrapper fmod */ +{ +#ifdef _IEEE_LIBM + return __ieee754_fmodl(x,y); +#else + double z; + z = __ieee754_fmodl(x,y); + if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z; + if(y==0.0) { + return __kernel_standard(x,y,27); /* fmod(x,0) */ + } else + return z; +#endif +} Index: src/tests/lib/libm/t_fmod.c diff -u /dev/null src/tests/lib/libm/t_fmod.c:1.1 --- /dev/null Tue Nov 12 16:48:39 2013 +++ src/tests/lib/libm/t_fmod.c Tue Nov 12 16:48:39 2013 @@ -0,0 +1,63 @@ +/* $NetBSD: t_fmod.c,v 1.1 2013/11/12 16:48:39 joerg Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <atf-c.h> +#include <float.h> +#include <math.h> + +ATF_TC(fmod); +ATF_TC_HEAD(fmod, tc) +{ + atf_tc_set_md_var(tc, "descr","Check fmod family"); +} + +ATF_TC_BODY(fmod, tc) +{ + ATF_CHECK(fmodf(2.0, 1.0) == 0); + ATF_CHECK(fmod(2.0, 1.0) == 0); + ATF_CHECK(fmodl(2.0, 1.0) == 0); + + ATF_CHECK(fmodf(2.0, 0.5) == 0); + ATF_CHECK(fmod(2.0, 0.5) == 0); + ATF_CHECK(fmodl(2.0, 0.5) == 0); + + ATF_CHECK(fabsf(fmodf(1.0, 0.1) - 0.1) <= 55 * FLT_EPSILON); + ATF_CHECK(fabs(fmod(1.0, 0.1) - 0.1) <= 55 * DBL_EPSILON); + ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fmod); + + return atf_no_error(); +}