diff --git a/modules/rostests/apitests/crt/gen_math_tests.py b/modules/rostests/apitests/crt/gen_math_tests.py index c69c8c33e2a..8ffbfe6ece1 100644 --- a/modules/rostests/apitests/crt/gen_math_tests.py +++ b/modules/rostests/apitests/crt/gen_math_tests.py @@ -233,6 +233,19 @@ def generate_sqrt_table(func_name = "sqrt", typecode = 'd'): def generate_sqrtf_table(): generate_sqrt_table("sqrtf", 'f') +def generate_tan_table(func_name = "tan", typecode = 'd'): + gen_table_header(func_name) + gen_table_range(func_name, typecode, mp.tan, -0.5 * mp.pi, -0.499, 23, 1) + gen_table_range(func_name, typecode, mp.tan, -0.5, -2 * sys.float_info.epsilon, 23, 1) + gen_table_range(func_name, typecode, mp.tan, -sys.float_info.epsilon, sys.float_info.epsilon, 7, 1) + gen_table_range(func_name, typecode, mp.tan, 2 * sys.float_info.epsilon, 0.5, 23, 1) + gen_table_range(func_name, typecode, mp.tan, 0.501, 0.5 * mp.pi, 23, 1) + gen_table_range(func_name, typecode, mp.tan, 10.501 * mp.pi, 11.499 * mp.pi, 5, 1) + print("};\n") + +def generate_tanf_table(): + generate_tan_table("tanf", 'f') + # Dictionary to map math function names to generator functions TABLE_FUNCTIONS = { "acos": generate_acos_table, @@ -253,6 +266,8 @@ TABLE_FUNCTIONS = { "sinf": generate_sinf_table, "sqrt": generate_sqrt_table, "sqrtf": generate_sqrtf_table, + "tan": generate_tan_table, + "tanf": generate_tanf_table, } def main(): diff --git a/modules/rostests/apitests/crt/tan.c b/modules/rostests/apitests/crt/tan.c new file mode 100644 index 00000000000..a37adebc4e5 --- /dev/null +++ b/modules/rostests/apitests/crt/tan.c @@ -0,0 +1,403 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Tests for tan + * COPYRIGHT: Copyright 2021 Timo Kreuzer + */ + +#if !defined(_CRTBLD) && !defined(_M_IX86) +#define _CRTBLD // we don't want inline tan! +#endif +#include "math_helpers.h" + +#ifdef _MSC_VER +#pragma function(tan) +#endif + +#if !defined(_M_IX86) +#define HAS_TANF +#elif (defined(TEST_UCRTBASE) || defined(TEST_STATIC_CRT)) +#define HAS_LIBM_SSE2 +#endif + + +// These are expected to match exactly +static TESTENTRY_DBL s_tan_exact_tests[] = +{ + { 0x0000000000000000 /* 0.000000 */, 0x0000000000000000 /* 0.000000 */ }, + { 0x8000000000000000 /* -0.000000 */, 0x8000000000000000 /* -0.000000 */ }, + { 0x7ff0000000000000 /* 1.#INF00 */, 0xfff8000000000000 /* -1.#IND00 */ }, + { 0x7ff0000000000001 /* 1.#SNAN0 */, 0x7ff8000000000001 /* 1.#QNAN0 */ }, + { 0x7ff7ffffffffffff /* 1.#SNAN0 */, 0x7fffffffffffffff /* 1.#QNAN0 */ }, + { 0x7ff8000000000000 /* 1.#QNAN0 */, 0x7ff8000000000000 /* 1.#QNAN0 */ }, + { 0x7ff8000000000001 /* 1.#QNAN0 */, 0x7ff8000000000001 /* 1.#QNAN0 */ }, + { 0x7fffffffffffffff /* 1.#QNAN0 */, 0x7fffffffffffffff /* 1.#QNAN0 */ }, + { 0xfff0000000000000 /* -1.#INF00 */, 0xfff8000000000000 /* -1.#IND00 */ }, + { 0xfff0000000000001 /* -1.#SNAN0 */, 0xfff8000000000001 /* -1.#QNAN0 */ }, + { 0xfff7ffffffffffff /* -1.#SNAN0 */, 0xffffffffffffffff /* -1.#QNAN0 */ }, + { 0xfff8000000000000 /* -1.#IND00 */, 0xfff8000000000000 /* -1.#IND00 */ }, + { 0xfff8000000000001 /* -1.#QNAN0 */, 0xfff8000000000001 /* -1.#QNAN0 */ }, + { 0xffffffffffffffff /* -1.#QNAN0 */, 0xffffffffffffffff /* -1.#QNAN0 */ }, +}; + +void Test_tan_exact(void) +{ + for (int i = 0; i < _countof(s_tan_exact_tests); i++) + { + double x = u64_to_dbl(s_tan_exact_tests[i].x); + double z = tan(x); + ok_eq_dbl_exact("tan", s_tan_exact_tests[i].x, z, s_tan_exact_tests[i].result); + } +} + +// This table is autogenerated by `python gen_math_tests.py tan` +static TESTENTRY_DBL_APPROX s_tan_approx_tests[] = +{ +// { x, { y_rounded, y_difference } } +#if !(defined(_M_IX86) && defined(TEST_MSVCRT)) + { -0x1.921fb54442d18p+0, { -0x1.d02967c31cdb5p+53, 0x1.f3c72fe49aa2ap-3 }, 1 }, // tan(-1.5707963267948966) == -16331239353195369.756 +#endif + { -0x1.85a6ec9bbc564p+0, { -0x1.48292602db3dfp+4, -0x1.59080789054e6p-52 }, 1 }, // tan(-1.5220783119405832) == -20.510046015889994508 + { -0x1.792e23f335dafp+0, { -0x1.4761710422f56p+3, 0x1.e3d55dad3df46p-52 }, 1 }, // tan(-1.4733602970862696) == -10.230644710616313666 + { -0x1.6cb55b4aaf5fbp+0, { -0x1.b2c590c42b471p+2, -0x1.5d53989828de4p-52 }, 1 }, // tan(-1.4246422822319562) == -6.7933084407533085002 + { -0x1.603c92a228e46p+0, { -0x1.4440b5bd4111cp+2, -0x1.abec5d54c2abap-52 }, 1 }, // tan(-1.3759242673776426) == -5.0664495800195052214 + { -0x1.53c3c9f9a2692p+0, { -0x1.0184ebdc8b27dp+2, -0x1.211209852aafdp-52 }, 1 }, // tan(-1.3272062525233292) == -4.0237378743883003572 + { -0x1.474b01511beddp+0, { -0x1.a959c7c899705p+1, 0x1.e16a925ce3d25p-54 }, 1 }, // tan(-1.2784882376690156) == -3.3230523805131063697 + { -0x1.3ad238a895729p+0, { -0x1.68ac5e279dd0bp+1, -0x1.d4cdade9a4c1ep-54 }, 1 }, // tan(-1.2297702228147023) == -2.8177602475585722303 + { -0x1.2e5970000ef74p+0, { -0x1.379ee31c647b3p+1, -0x1.5e9c8a91c43d2p-54 }, 1 }, // tan(-1.1810522079603887) == -2.4345363510737683882 + { -0x1.21e0a757887c0p+0, { -0x1.10fa3b265671bp+1, -0x1.d629f0bf05f70p-53 }, 1 }, // tan(-1.1323341931060753) == -2.1326364457317035047 + { -0x1.1567deaf0200bp+0, { -0x1.e33a2bc8b934bp+0, 0x1.d4ca996c14e19p-56 }, 1 }, // tan(-1.0836161782517617) == -1.8876063694999227506 + { -0x1.08ef16067b857p+0, { -0x1.af12917d3b0e2p+0, 0x1.f2079bbcce4a5p-56 }, 1 }, // tan(-1.0348981633974483) == -1.6838770800341582309 + { -0x1.f8ec9abbea145p-1, { -0x1.82d4f782a01c3p+0, 0x1.72f6a4728aa93p-54 }, 1 }, // tan(-0.9861801485431348) == -1.5110621160421124104 + { -0x1.dffb096add1dcp-1, { -0x1.5ca9a9f08c147p+0, 0x1.db383b0ec94fbp-54 }, 1 }, // tan(-0.9374621336888214) == -1.3619638645432857817 + { -0x1.c7097819d0273p-1, { -0x1.3b3f45fb0d102p+0, -0x1.b6d38abd7652cp-58 }, 1 }, // tan(-0.8887441188345079) == -1.2314342248837992837 + { -0x1.ae17e6c8c330ap-1, { -0x1.1d9debf5bcdadp+0, 0x1.4c70a3c0c8823p-54 }, 1 }, // tan(-0.8400261039801944) == -1.115690944189604722 + { -0x1.95265577b63a1p-1, { -0x1.030b3d77c014ep+0, 0x1.3667d9fcd7a86p-54 }, 1 }, // tan(-0.7913080891258809) == -1.011890260444562472 + { -0x1.7c34c426a9438p-1, { -0x1.d5f079b0e6c4cp-1, 0x1.5688a6674ac98p-56 }, 1 }, // tan(-0.7425900742715674) == -0.91785030636254692302 + { -0x1.634332d59c4cfp-1, { -0x1.a9ea6c741d9ebp-1, 0x1.f3c3e52eca656p-55 }, 1 }, // tan(-0.6938720594172539) == -0.83186663548877720764 + { -0x1.4a51a1848f566p-1, { -0x1.8152f115f047fp-1, -0x1.9227d5686fc02p-56 }, 1 }, // tan(-0.6451540445629405) == -0.75258592026524686562 + { -0x1.31601033825fdp-1, { -0x1.5b9b116956dd4p-1, -0x1.021da723d81edp-56 }, 1 }, // tan(-0.596436029708627) == -0.67891745005493443777 + { -0x1.186e7ee275694p-1, { -0x1.384df6b48888ep-1, -0x1.c79d9269e0dfdp-56 }, 1 }, // tan(-0.5477180148543135) == -0.60996981576706035516 + { -0x1.fef9db22d0e56p-2, { -0x1.170adce3a684cp-1, 0x1.155476f2da1afp-56 }, 1 }, // tan(-0.499) == -0.54500475195823970427 + { -0x1.0000000000000p-1, { -0x1.17b4f5bf3474ap-1, -0x1.0c5e59201e209p-55 }, 1 }, // tan(-0.5) == -0.54630248984379051326 + { -0x1.e8ba2e8ba2e8cp-2, { -0x1.08c7caac28aa4p-1, 0x1.28cd16180fba1p-55 }, 1 }, // tan(-0.4772727272727273) == -0.51714928962276870529 + { -0x1.d1745d1745d18p-2, { -0x1.f466d6406bb86p-2, 0x1.9028ce89507bdp-56 }, 1 }, // tan(-0.4545454545454546) == -0.48867354171937225134 + { -0x1.ba2e8ba2e8ba4p-2, { -0x1.d7e21b76dc1a9p-2, -0x1.819c73e1623a4p-63 }, 1 }, // tan(-0.4318181818181819) == -0.46082346833193327268 + { -0x1.a2e8ba2e8ba30p-2, { -0x1.bbf4be4924d13p-2, 0x1.210bfe1eac791p-57 }, 1 }, // tan(-0.40909090909090917) == -0.43355080911096981804 + { -0x1.8ba2e8ba2e8bcp-2, { -0x1.a092eb7d16791p-2, -0x1.17dd013191ce5p-57 }, 1 }, // tan(-0.38636363636363646) == -0.40681045485472917193 + { -0x1.745d1745d1748p-2, { -0x1.85b18d5ff2a82p-2, 0x1.c73ccb0f5765fp-56 }, 1 }, // tan(-0.36363636363636376) == -0.38056012056464547407 + { -0x1.5d1745d1745d4p-2, { -0x1.6b46381f7ab06p-2, 0x1.ef981da78f64dp-56 }, 1 }, // tan(-0.34090909090909105) == -0.35476005260595430779 + { -0x1.45d1745d17460p-2, { -0x1.5147181f7a3e1p-2, -0x1.f38537f209091p-57 }, 1 }, // tan(-0.31818181818181834) == -0.32937276546596024018 + { -0x1.2e8ba2e8ba2ecp-2, { -0x1.37aae2091da45p-2, -0x1.28d36d7bc8acfp-60 }, 1 }, // tan(-0.29545454545454564) == -0.3043628042281947842 + { -0x1.1745d1745d178p-2, { -0x1.1e68c45a69fa8p-2, -0x1.3400e52091ac5p-56 }, 1 }, // tan(-0.27272727272727293) == -0.27969652940600521767 + { -0x1.0000000000004p-2, { -0x1.05785a43c4c5ap-2, -0x1.47e7420a285bep-57 }, 1 }, // tan(-0.2500000000000002) == -0.25534192122103650303 + { -0x1.d1745d1745d20p-3, { -0x1.d9a33f4fbd685p-3, 0x1.154219988e9c3p-57 }, 1 }, // tan(-0.22727272727272751) == -0.23126840078446177865 + { -0x1.a2e8ba2e8ba38p-3, { -0x1.a8d9cc2f752f2p-3, 0x1.0dc2a8dcacd37p-57 }, 1 }, // tan(-0.2045454545454548) == -0.20744666595296439683 + { -0x1.745d1745d1750p-3, { -0x1.788595522f833p-3, 0x1.48cb47f93cc67p-57 }, 1 }, // tan(-0.1818181818181821) == -0.18384853989658863302 + { -0x1.45d1745d17468p-3, { -0x1.48985912bccaap-3, -0x1.9ba520513e51cp-57 }, 1 }, // tan(-0.1590909090909094) == -0.16044683063919269467 + { -0x1.1745d1745d180p-3, { -0x1.19044864d16f4p-3, -0x1.c642f9fbf57f4p-57 }, 1 }, // tan(-0.1363636363636367) == -0.13721520002052724051 + { -0x1.d1745d1745d30p-4, { -0x1.d377eca4ea002p-4, -0x1.1caa3d80e4684p-61 }, 1 }, // tan(-0.11363636363636398) == -0.11412804068697826647 + { -0x1.745d1745d1760p-4, { -0x1.756490c3f31dbp-4, 0x1.b6724a0e4e6bfp-59 }, 1 }, // tan(-0.09090909090909127) == -0.091160359849886612809 + { -0x1.1745d1745d190p-4, { -0x1.17b4cf79cc8d0p-4, -0x1.3bc015ade5d5cp-59 }, 1 }, // tan(-0.06818181818181857) == -0.068287668659454017125 + { -0x1.745d1745d1780p-5, { -0x1.749ecbcd3dedbp-5, -0x1.14076fc22d284p-59 }, 1 }, // tan(-0.04545454545454586) == -0.045485876131292813301 + { -0x1.745d1745d17c0p-6, { -0x1.746d81cc44785p-6, 0x1.e86df438a8135p-60 }, 1 }, // tan(-0.02272727272727315) == -0.022731186633854887507 + { -0x1.0000000000000p-51, { -0x1.0000000000000p-51, -0x1.5555555555555p-155 }, 1 }, // tan(-4.440892098500626e-16) == -4.4408920985006261617e-16 + { -0x1.0000000000000p-52, { -0x1.0000000000000p-52, -0x1.5555555555555p-158 }, 1 }, // tan(-2.220446049250313e-16) == -2.2204460492503130808e-16 + { -0x1.5555555555556p-53, { -0x1.5555555555556p-53, -0x1.948b0fcd6e9e3p-160 }, 1 }, // tan(-1.4802973661668756e-16) == -1.4802973661668755516e-16 + { -0x1.5555555555556p-54, { -0x1.5555555555556p-54, -0x1.948b0fcd6e9e3p-163 }, 1 }, // tan(-7.401486830834378e-17) == -7.4014868308343777579e-17 + { 0x0.0p+0, { 0x0.0p+0, 0x0.0p+0 }, 1 }, // tan(0.0) == 0.0 + { 0x1.5555555555554p-54, { 0x1.5555555555554p-54, 0x1.948b0fcd6e9dcp-163 }, 1 }, // tan(7.401486830834375e-17) == 7.4014868308343752927e-17 + { 0x1.5555555555554p-53, { 0x1.5555555555554p-53, 0x1.948b0fcd6e9dcp-160 }, 1 }, // tan(1.480297366166875e-16) == 1.4802973661668750585e-16 + { 0x1.0000000000000p-52, { 0x1.0000000000000p-52, 0x1.5555555555555p-158 }, 1 }, // tan(2.220446049250313e-16) == 2.2204460492503130808e-16 + { 0x1.0000000000000p-51, { 0x1.0000000000000p-51, 0x1.5555555555555p-155 }, 1 }, // tan(4.440892098500626e-16) == 4.4408920985006261617e-16 + { 0x1.745d1745d17c0p-6, { 0x1.746d81cc44785p-6, -0x1.e86df438a8135p-60 }, 1 }, // tan(0.02272727272727315) == 0.022731186633854887507 + { 0x1.745d1745d1780p-5, { 0x1.749ecbcd3dedbp-5, 0x1.14076fc22d284p-59 }, 1 }, // tan(0.04545454545454586) == 0.045485876131292813301 + { 0x1.1745d1745d190p-4, { 0x1.17b4cf79cc8d0p-4, 0x1.3bc015ade5d5cp-59 }, 1 }, // tan(0.06818181818181857) == 0.068287668659454017125 + { 0x1.745d1745d1760p-4, { 0x1.756490c3f31dbp-4, -0x1.b6724a0e4e6bfp-59 }, 1 }, // tan(0.09090909090909127) == 0.091160359849886612809 + { 0x1.d1745d1745d30p-4, { 0x1.d377eca4ea002p-4, 0x1.1caa3d80e4684p-61 }, 1 }, // tan(0.11363636363636398) == 0.11412804068697826647 + { 0x1.1745d1745d180p-3, { 0x1.19044864d16f4p-3, 0x1.c642f9fbf57f4p-57 }, 1 }, // tan(0.1363636363636367) == 0.13721520002052724051 + { 0x1.45d1745d17468p-3, { 0x1.48985912bccaap-3, 0x1.9ba520513e51cp-57 }, 1 }, // tan(0.1590909090909094) == 0.16044683063919269467 + { 0x1.745d1745d1750p-3, { 0x1.788595522f833p-3, -0x1.48cb47f93cc67p-57 }, 1 }, // tan(0.1818181818181821) == 0.18384853989658863302 + { 0x1.a2e8ba2e8ba38p-3, { 0x1.a8d9cc2f752f2p-3, -0x1.0dc2a8dcacd37p-57 }, 1 }, // tan(0.2045454545454548) == 0.20744666595296439683 + { 0x1.d1745d1745d20p-3, { 0x1.d9a33f4fbd685p-3, -0x1.154219988e9c3p-57 }, 1 }, // tan(0.22727272727272751) == 0.23126840078446177865 + { 0x1.0000000000004p-2, { 0x1.05785a43c4c5ap-2, 0x1.47e7420a285bep-57 }, 1 }, // tan(0.2500000000000002) == 0.25534192122103650303 + { 0x1.1745d1745d178p-2, { 0x1.1e68c45a69fa8p-2, 0x1.3400e52091ac5p-56 }, 1 }, // tan(0.27272727272727293) == 0.27969652940600521767 + { 0x1.2e8ba2e8ba2ecp-2, { 0x1.37aae2091da45p-2, 0x1.28d36d7bc8acfp-60 }, 1 }, // tan(0.29545454545454564) == 0.3043628042281947842 + { 0x1.45d1745d17460p-2, { 0x1.5147181f7a3e1p-2, 0x1.f38537f209091p-57 }, 1 }, // tan(0.31818181818181834) == 0.32937276546596024018 + { 0x1.5d1745d1745d4p-2, { 0x1.6b46381f7ab06p-2, -0x1.ef981da78f64dp-56 }, 1 }, // tan(0.34090909090909105) == 0.35476005260595430779 + { 0x1.745d1745d1748p-2, { 0x1.85b18d5ff2a82p-2, -0x1.c73ccb0f5765fp-56 }, 1 }, // tan(0.36363636363636376) == 0.38056012056464547407 + { 0x1.8ba2e8ba2e8bcp-2, { 0x1.a092eb7d16791p-2, 0x1.17dd013191ce5p-57 }, 1 }, // tan(0.38636363636363646) == 0.40681045485472917193 + { 0x1.a2e8ba2e8ba30p-2, { 0x1.bbf4be4924d13p-2, -0x1.210bfe1eac791p-57 }, 1 }, // tan(0.40909090909090917) == 0.43355080911096981804 + { 0x1.ba2e8ba2e8ba4p-2, { 0x1.d7e21b76dc1a9p-2, 0x1.819c73e1623a4p-63 }, 1 }, // tan(0.4318181818181819) == 0.46082346833193327268 + { 0x1.d1745d1745d18p-2, { 0x1.f466d6406bb86p-2, -0x1.9028ce89507bdp-56 }, 1 }, // tan(0.4545454545454546) == 0.48867354171937225134 + { 0x1.e8ba2e8ba2e8cp-2, { 0x1.08c7caac28aa4p-1, -0x1.28cd16180fba1p-55 }, 1 }, // tan(0.4772727272727273) == 0.51714928962276870529 + { 0x1.0000000000000p-1, { 0x1.17b4f5bf3474ap-1, 0x1.0c5e59201e209p-55 }, 1 }, // tan(0.5) == 0.54630248984379051326 + { 0x1.0083126e978d5p-1, { 0x1.185f3e353789ap-1, -0x1.1164e2f8dc326p-55 }, 1 }, // tan(0.501) == 0.5476016464197243897 + { 0x1.1968b9587f770p-1, { 0x1.39a5b1895ef0fp-1, 0x1.69076f1898249p-55 }, 1 }, // tan(0.5496271057634043) == 0.61259226610079224346 + { 0x1.324e60426760cp-1, { 0x1.5cf7a819e93efp-1, 0x1.c1f568456e356p-56 }, 1 }, // tan(0.5982542115268088) == 0.68157697025583088509 + { 0x1.4b34072c4f4a7p-1, { 0x1.82b607606becfp-1, -0x1.3d8f67e5f35dfp-56 }, 1 }, // tan(0.6468813172902131) == 0.75529501964589394413 + { 0x1.6419ae1637343p-1, { 0x1.ab55d25bca8e2p-1, 0x1.4bc370a5ac8f2p-57 }, 1 }, // tan(0.6955084230536176) == 0.83463914270876339085 + { 0x1.7cff55001f1dep-1, { 0x1.d76639191a092p-1, 0x1.e083312b5f5f2p-55 }, 1 }, // tan(0.7441355288170219) == 0.92070177489678633678 + { 0x1.95e4fbea0707ap-1, { 0x1.03cc7485ba1c0p+0, -0x1.ffd40f6f90912p-54 }, 1 }, // tan(0.7927626345804264) == 1.0148384882432849308 + { 0x1.aecaa2d3eef15p-1, { 0x1.1e66d60e326d4p+0, -0x1.61a7ab456a939p-54 }, 1 }, // tan(0.8413897403438307) == 1.1187566551838487371 + { 0x1.c7b049bdd6db0p-1, { 0x1.3c117f3d5196bp+0, -0x1.eaea7607b3a57p-54 }, 1 }, // tan(0.8900168461072351) == 1.2346419834808225514 + { 0x1.e095f0a7bec4cp-1, { 0x1.5d8723ffe6398p+0, 0x1.b3677f868b65fp-55 }, 1 }, // tan(0.9386439518706395) == 1.3653433322672068801 + { 0x1.f97b9791a6ae7p-1, { 0x1.83c0173e2d001p+0, -0x1.54207765ad0b9p-55 }, 1 }, // tan(0.9872710576340439) == 1.5146498228832571873 + { 0x1.09309f3dc74c1p+0, { 0x1.b00e5a163e86fp+0, 0x1.36a110d4cecd5p-54 }, 1 }, // tan(1.0358981633974482) == 1.6877189926440470787 + { 0x1.15a372b2bb40fp+0, { 0x1.e44a7f426cc8ap+0, 0x1.3733708d99df4p-55 }, 1 }, // tan(1.0845252691608527) == 1.8917617356462721805 + { 0x1.22164627af35dp+0, { 0x1.118f3cd8a0a0ap+1, -0x1.4d890bd026cb3p-53 }, 1 }, // tan(1.1331523749242571) == 2.1371837671042655745 + { 0x1.2e89199ca32abp+0, { 0x1.384442285e0a4p+1, 0x1.e023f3b8735f6p-55 }, 1 }, // tan(1.1817794806876616) == 2.4395830819231197305 + { 0x1.3afbed11971f8p+0, { 0x1.69671e3a41aecp+1, 0x1.521a4291c1306p-54 }, 1 }, // tan(1.2304065864510658) == 2.8234594139533922453 + { 0x1.476ec0868b146p+0, { 0x1.aa316a5fb43c9p+1, -0x1.52dbeccfa5e16p-55 }, 1 }, // tan(1.2790336922144703) == 3.3296330420784880554 + { 0x1.53e193fb7f094p+0, { 0x1.02052d9240193p+2, 0x1.f3c7273c87f91p-53 }, 1 }, // tan(1.3276607979778747) == 4.0315660408235942605 + { 0x1.6054677072fe1p+0, { 0x1.44dfe447af0fdp+2, 0x1.9921e6edfc0f1p-53 }, 1 }, // tan(1.376287903741279) == 5.0761652660405591318 + { 0x1.6cc73ae566f2fp+0, { 0x1.b398a2b7194e6p+2, -0x1.41da4eda108d7p-56 }, 1 }, // tan(1.4249150095046834) == 6.8061911380839088362 + { 0x1.793a0e5a5ae7dp+0, { 0x1.47ff1e9ecf9bap+3, 0x1.858f5bd530970p-51 }, 1 }, // tan(1.4735421152680879) == 10.249892530610726703 + { 0x1.85ace1cf4edcbp+0, { 0x1.48c674106788dp+4, -0x1.7df7c58540c45p-50 }, 1 }, // tan(1.5221692210314923) == 20.548450531081970734 +#if !(defined(_M_IX86) && defined(TEST_MSVCRT)) + { 0x1.921fb54442d18p+0, { 0x1.d02967c31cdb5p+53, -0x1.f3c72fe49aa2ap-3 }, 1 }, // tan(1.5707963267948966) == 16331239353195369.756 +#endif + { 0x1.07eb3e0e397c5p+5, { -0x1.3e4f101260dc1p+8, -0x1.2b5a2b39a6a8bp-46 }, 1 }, // tan(32.989864455346414) == -318.30883898606051004 + { 0x1.0e30855693b63p+5, { -0x1.fe64dee19cc97p-1, 0x1.77d5738519368p-55 }, 1 }, // tan(33.77369182241707) == -0.99686333183344085029 +#if !(defined(_M_IX86) && defined(TEST_MSVCRT)) + { 0x1.1475cc9eedf01p+5, { 0x1.3ddc5bce200bbp-49, 0x1.15860679cd558p-103 }, 1 }, // tan(34.55751918948773) == 2.2056021997384124344e-15 +#endif + { 0x1.1abb13e74829ep+5, { 0x1.fe64dee19cc66p-1, 0x1.002beedbbd0f9p-55 }, 1 }, // tan(35.34134655655838) == 0.99686333183343547872 + { 0x1.21005b2fa263cp+5, { 0x1.3e4f10125faffp+8, -0x1.2349bf9baab7cp-48 }, 1 }, // tan(36.125173923629035) == 318.30883898578752729 +}; + +void Test_tan_approx(void) +{ + for (int i = 0; i < _countof(s_tan_approx_tests); i++) + { + double x = s_tan_approx_tests[i].x; + double expected = s_tan_approx_tests[i].expected.rounded; + double z = tan(x); + int64_t error = abs(ulp_error_precise(&s_tan_approx_tests[i].expected, z)); + ok(error <= s_tan_approx_tests[i].max_error, + "tan(%.17e) = %.17e, expected %.17e, error %I64d ULPs, max %u ULPs\n", + x, z, expected, error, s_tan_approx_tests[i].max_error); + } +} + +#ifdef HAS_TANF + +// These are expected to match exactly +static TESTENTRY_DBL s_tanf_exact_tests[] = +{ + { 0x00000000 /* 0.000000 */, 0x00000000 /* 0.000000 */ }, + { 0x80000000 /* -0.000000 */, 0x00000000 /* 0.000000 */ }, + { 0x7f800000 /* 1.#INF00 */, 0x00000000 /* 0.000000 */ }, + { 0x7f800001 /* 1.#SNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0x7fBFffff /* 1.#SNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0x7fC00000 /* 1.#QNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0x7fC80001 /* 1.#QNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0x7fFfffff /* 1.#QNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0xff800000 /* -1.#INF00 */, 0x00000000 /* 0.000000 */ }, + { 0xff800001 /* -1.#SNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0xffBfffff /* -1.#SNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0xffC00000 /* -1.#IND00 */, 0x00000000 /* 0.000000 */ }, + { 0xfff80001 /* -1.#QNAN0 */, 0x00000000 /* 0.000000 */ }, + { 0xffffffff /* -1.#QNAN0 */, 0x00000000 /* 0.000000 */ }, +}; + +void Test_tanf_exact(void) +{ + for (int i = 0; i < _countof(s_tanf_exact_tests); i++) + { + float x = u64_to_dbl(s_tanf_exact_tests[i].x); + float z = tanf(x); + ok_eq_flt_exact("tanf", s_tanf_exact_tests[i].x, z, s_tanf_exact_tests[i].result); + } +} + +#endif // HAS_TANF + +#if defined(HAS_TANF) || defined(HAS_LIBM_SSE2) + +static TESTENTRY_DBL_APPROX s_tanf_approx_tests[] = +{ +// { x, { y_rounded, y_difference } } + { -0x1.921fb60000000p+0, { 0x1.5d14946dc9897p+24, 0x1.759086954a140p-30 }, 1 }, // tanf(-1.5707963705062866) == 22877332.428856459874 + { -0x1.85a6ec0000000p+0, { -0x1.482915fa9ee30p+4, -0x1.bbeceea93d6b7p-50 }, 1 }, // tanf(-1.522078275680542) == -20.510030726420326749 + { -0x1.792e240000000p+0, { -0x1.476171ad10b84p+3, -0x1.5815b396155f9p-51 }, 1 }, // tanf(-1.473360300064087) == -10.230645025270640389 + { -0x1.6cb55c0000000p+0, { -0x1.b2c5991d60457p+2, 0x1.b292872ff2d76p-53 }, 1 }, // tanf(-1.4246423244476318) == -6.7933104311824397462 + { -0x1.603c920000000p+0, { -0x1.4440b18419367p+2, -0x1.750eac0a12690p-55 }, 1 }, // tanf(-1.3759242296218872) == -5.0664485731148039398 + { -0x1.53c3ca0000000p+0, { -0x1.0184ebf7e6818p+2, -0x1.1aebbc20cd7b5p-52 }, 1 }, // tanf(-1.3272062540054321) == -4.0237378998663404739 + { -0x1.474b020000000p+0, { -0x1.a959cbe5ad45ep+1, -0x1.1f19c933c0298p-53 }, 1 }, // tanf(-1.278488278388977) == -3.3230528708905203851 + { -0x1.3ad2380000000p+0, { -0x1.68ac5b3610f2ep+1, 0x1.ce3a53388d573p-53 }, 1 }, // tanf(-1.2297701835632324) == -2.8177598966593879964 + { -0x1.2e59700000000p+0, { -0x1.379ee31c30a5cp+1, 0x1.7fd7a0966bccep-53 }, 1 }, // tanf(-1.1810522079467773) == -2.4345363509794831215 + { -0x1.21e0a80000000p+0, { -0x1.10fa3cf9ad29bp+1, -0x1.18a3dc72f2dc1p-54 }, 1 }, // tanf(-1.1323342323303223) == -2.1326366633532650217 + { -0x1.1567de0000000p+0, { -0x1.e33a28aa2717fp+0, 0x1.68562cb63425ep-54 }, 1 }, // tanf(-1.0836161375045776) == -1.8876061835681806951 + { -0x1.08ef160000000p+0, { -0x1.af1291645e0ecp+0, -0x1.82c32a8763e67p-55 }, 1 }, // tanf(-1.0348981618881226) == -1.6838770742452267435 + { -0x1.f8ec9a0000000p-1, { -0x1.82d4f64e228edp+0, 0x1.96d28d6d91903p-54 }, 1 }, // tanf(-0.9861801266670227) == -1.5110620442160850547 + { -0x1.dffb0a0000000p-1, { -0x1.5ca9aac56f660p+0, -0x1.cf1198d68e402p-54 }, 1 }, // tanf(-0.9374621510505676) == -1.3619639141101275053 + { -0x1.c709780000000p-1, { -0x1.3b3f45da9295cp+0, 0x1.63bd7d7c7576bp-54 }, 1 }, // tanf(-0.8887441158294678) == -1.2314342173218254867 + { -0x1.ae17e60000000p-1, { -0x1.1d9deb1467c2fp+0, 0x1.d93dccaaa6e15p-55 }, 1 }, // tanf(-0.8400260806083679) == -1.11569089172531805 + { -0x1.9526560000000p-1, { -0x1.030b3e01ab2b9p+0, 0x1.f0be43b2a457bp-54 }, 1 }, // tanf(-0.7913081049919128) == -1.0118902925561724693 + { -0x1.7c34c40000000p-1, { -0x1.d5f07969ab903p-1, 0x1.d7d4d48e87fc3p-57 }, 1 }, // tanf(-0.742590069770813) == -0.91785029807013561563 + { -0x1.6343320000000p-1, { -0x1.a9ea6b0aafabap-1, 0x1.85b16fcacb454p-56 }, 1 }, // tanf(-0.6938720345497131) == -0.83186659341284683419 + { -0x1.4a51a20000000p-1, { -0x1.8152f1d74b1a8p-1, 0x1.dd7a25caf317ap-55 }, 1 }, // tanf(-0.6451540589332581) == -0.75258594277470520037 + { -0x1.3160100000000p-1, { -0x1.5b9b111e16825p-1, -0x1.cd18dbc056bb1p-57 }, 1 }, // tanf(-0.5964360237121582) == -0.67891744129451993135 + { -0x1.186e7e0000000p-1, { -0x1.384df57dd15a7p-1, -0x1.f2f27bdb30755p-55 }, 1 }, // tanf(-0.5477179884910583) == -0.60996977959500936342 + { -0x1.fef9dc0000000p-2, { -0x1.170add731774cp-1, -0x1.b4799c456e9b6p-55 }, 1 }, // tanf(-0.49900001287460327) == -0.54500476865698881682 + { -0x1.0000000000000p-1, { -0x1.17b4f5bf3474ap-1, -0x1.0c5e59201e209p-55 }, 1 }, // tanf(-0.5) == -0.54630248984379051326 + { -0x1.e8ba2e0000000p-2, { -0x1.08c7ca53ab12cp-1, 0x1.f57d7c1223293p-58 }, 1 }, // tanf(-0.47727271914482117) == -0.51714927932110787298 + { -0x1.d1745e0000000p-2, { -0x1.f466d760b947fp-2, -0x1.21b5240e6aa7ap-56 }, 1 }, // tanf(-0.4545454680919647) == -0.48867355850081391394 + { -0x1.ba2e8c0000000p-2, { -0x1.d7e21be7b824ep-2, -0x1.280c597324109p-58 }, 1 }, // tanf(-0.4318181872367859) == -0.46082347490122266677 + { -0x1.a2e8ba0000000p-2, { -0x1.bbf4be11d9713p-2, -0x1.1fd834abca2e6p-56 }, 1 }, // tanf(-0.40909090638160706) == -0.43355080589241020045 + { -0x1.8ba2e80000000p-2, { -0x1.a092eaa41806cp-2, 0x1.7c80008b49c5bp-58 }, 1 }, // tanf(-0.3863636255264282) == -0.40681044222401995842 + { -0x1.745d180000000p-2, { -0x1.85b18e3517fa5p-2, 0x1.4fde597478211p-58 }, 1 }, // tanf(-0.3636363744735718) == -0.38056013297136309192 + { -0x1.5d17460000000p-2, { -0x1.6b463853e1f6ap-2, 0x1.3ea3b0f12ae57p-56 }, 1 }, // tanf(-0.34090909361839294) == -0.35476005565623456799 + { -0x1.45d1740000000p-2, { -0x1.514717b849998p-2, 0x1.fd76e2939aa2bp-59 }, 1 }, // tanf(-0.3181818127632141) == -0.32937275945951105182 + { -0x1.2e8ba20000000p-2, { -0x1.37aae10ad4551p-2, -0x1.f30aa8f232fc7p-60 }, 1 }, // tanf(-0.2954545319080353) == -0.30436278942678024642 + { -0x1.1745d20000000p-2, { -0x1.1e68c4f0f95f7p-2, -0x1.1395a0da02fbap-58 }, 1 }, // tanf(-0.27272728085517883) == -0.27969653816975842782 + { -0x1.0000000000000p-2, { -0x1.05785a43c4c56p-2, 0x1.9c6bfe7769a3dp-58 }, 1 }, // tanf(-0.25) == -0.2553419212210362665 + { -0x1.d1745e0000000p-3, { -0x1.d9a34044ea216p-3, -0x1.fbfe898f560d7p-57 }, 1 }, // tanf(-0.22727273404598236) == -0.23126840791998466696 + { -0x1.a2e8ba0000000p-3, { -0x1.a8d9cbfee8c43p-3, 0x1.858552a968917p-59 }, 1 }, // tanf(-0.20454545319080353) == -0.20744666454001689251 + { -0x1.745d180000000p-3, { -0x1.78859612a9102p-3, 0x1.0b201e0d80102p-58 }, 1 }, // tanf(-0.1818181872367859) == -0.18384854549834278219 + { -0x1.45d1740000000p-3, { -0x1.489858b34005fp-3, -0x1.6ada9662e24cfp-57 }, 1 }, // tanf(-0.15909090638160706) == -0.16044682786014428528 + { -0x1.1745d20000000p-3, { -0x1.190448f315625p-3, -0x1.0c5ee14b4d884p-57 }, 1 }, // tanf(-0.13636364042758942) == -0.13721520416099611989 + { -0x1.d1745e0000000p-4, { -0x1.d377ed90ac31dp-4, 0x1.8d56873a5ced9p-59 }, 1 }, // tanf(-0.11363636702299118) == -0.11412804411771699806 + { -0x1.745d180000000p-4, { -0x1.7564917fadbdap-4, -0x1.1122d5adaf096p-59 }, 1 }, // tanf(-0.09090909361839294) == -0.091160362581703154502 + { -0x1.1745d20000000p-4, { -0x1.17b4d00616260p-4, 0x1.d3629eb18cc93p-58 }, 1 }, // tanf(-0.06818182021379471) == -0.068287670700905683024 + { -0x1.745d180000000p-5, { -0x1.749ecc87cf126p-5, -0x1.dcf4ecf92b84dp-59 }, 1 }, // tanf(-0.04545454680919647) == -0.045485877488746151899 + { -0x1.745d180000000p-6, { -0x1.746d82868b9cfp-6, 0x1.2e64b511833eap-63 }, 1 }, // tanf(-0.022727273404598236) == -0.022731187311529950934 + { -0x1.0000000000000p-51, { -0x1.0000000000000p-51, -0x1.5555555555555p-155 }, 1 }, // tanf(-4.440892098500626e-16) == -4.4408920985006261617e-16 + { -0x1.0000000000000p-52, { -0x1.0000000000000p-52, -0x1.5555555555555p-158 }, 1 }, // tanf(-2.220446049250313e-16) == -2.2204460492503130808e-16 + { -0x1.5555560000000p-53, { -0x1.5555560000000p-53, -0x1.948b122c3f36fp-160 }, 1 }, // tanf(-1.4802974102831747e-16) == -1.4802974102831747234e-16 + { -0x1.5555560000000p-54, { -0x1.5555560000000p-54, -0x1.948b122c3f36fp-163 }, 1 }, // tanf(-7.401487051415874e-17) == -7.401487051415873617e-17 + { 0x0.0p+0, { 0x0.0p+0, 0x0.0p+0 }, 1 }, // tanf(0.0) == 0.0 + { 0x1.5555560000000p-54, { 0x1.5555560000000p-54, 0x1.948b122c3f36fp-163 }, 1 }, // tanf(7.401487051415874e-17) == 7.401487051415873617e-17 + { 0x1.5555560000000p-53, { 0x1.5555560000000p-53, 0x1.948b122c3f36fp-160 }, 1 }, // tanf(1.4802974102831747e-16) == 1.4802974102831747234e-16 + { 0x1.0000000000000p-52, { 0x1.0000000000000p-52, 0x1.5555555555555p-158 }, 1 }, // tanf(2.220446049250313e-16) == 2.2204460492503130808e-16 + { 0x1.0000000000000p-51, { 0x1.0000000000000p-51, 0x1.5555555555555p-155 }, 1 }, // tanf(4.440892098500626e-16) == 4.4408920985006261617e-16 + { 0x1.745d180000000p-6, { 0x1.746d82868b9cfp-6, -0x1.2e64b511833eap-63 }, 1 }, // tanf(0.022727273404598236) == 0.022731187311529950934 + { 0x1.745d180000000p-5, { 0x1.749ecc87cf126p-5, 0x1.dcf4ecf92b84dp-59 }, 1 }, // tanf(0.04545454680919647) == 0.045485877488746151899 + { 0x1.1745d20000000p-4, { 0x1.17b4d00616260p-4, -0x1.d3629eb18cc93p-58 }, 1 }, // tanf(0.06818182021379471) == 0.068287670700905683024 + { 0x1.745d180000000p-4, { 0x1.7564917fadbdap-4, 0x1.1122d5adaf096p-59 }, 1 }, // tanf(0.09090909361839294) == 0.091160362581703154502 + { 0x1.d1745e0000000p-4, { 0x1.d377ed90ac31dp-4, -0x1.8d56873a5ced9p-59 }, 1 }, // tanf(0.11363636702299118) == 0.11412804411771699806 + { 0x1.1745d20000000p-3, { 0x1.190448f315625p-3, 0x1.0c5ee14b4d884p-57 }, 1 }, // tanf(0.13636364042758942) == 0.13721520416099611989 + { 0x1.45d1740000000p-3, { 0x1.489858b34005fp-3, 0x1.6ada9662e24cfp-57 }, 1 }, // tanf(0.15909090638160706) == 0.16044682786014428528 + { 0x1.745d180000000p-3, { 0x1.78859612a9102p-3, -0x1.0b201e0d80102p-58 }, 1 }, // tanf(0.1818181872367859) == 0.18384854549834278219 + { 0x1.a2e8ba0000000p-3, { 0x1.a8d9cbfee8c43p-3, -0x1.858552a968917p-59 }, 1 }, // tanf(0.20454545319080353) == 0.20744666454001689251 + { 0x1.d1745e0000000p-3, { 0x1.d9a34044ea216p-3, 0x1.fbfe898f560d7p-57 }, 1 }, // tanf(0.22727273404598236) == 0.23126840791998466696 + { 0x1.0000000000000p-2, { 0x1.05785a43c4c56p-2, -0x1.9c6bfe7769a3dp-58 }, 1 }, // tanf(0.25) == 0.2553419212210362665 + { 0x1.1745d20000000p-2, { 0x1.1e68c4f0f95f7p-2, 0x1.1395a0da02fbap-58 }, 1 }, // tanf(0.27272728085517883) == 0.27969653816975842782 + { 0x1.2e8ba20000000p-2, { 0x1.37aae10ad4551p-2, 0x1.f30aa8f232fc7p-60 }, 1 }, // tanf(0.2954545319080353) == 0.30436278942678024642 + { 0x1.45d1740000000p-2, { 0x1.514717b849998p-2, -0x1.fd76e2939aa2bp-59 }, 1 }, // tanf(0.3181818127632141) == 0.32937275945951105182 + { 0x1.5d17460000000p-2, { 0x1.6b463853e1f6ap-2, -0x1.3ea3b0f12ae57p-56 }, 1 }, // tanf(0.34090909361839294) == 0.35476005565623456799 + { 0x1.745d180000000p-2, { 0x1.85b18e3517fa5p-2, -0x1.4fde597478211p-58 }, 1 }, // tanf(0.3636363744735718) == 0.38056013297136309192 + { 0x1.8ba2e80000000p-2, { 0x1.a092eaa41806cp-2, -0x1.7c80008b49c5bp-58 }, 1 }, // tanf(0.3863636255264282) == 0.40681044222401995842 + { 0x1.a2e8ba0000000p-2, { 0x1.bbf4be11d9713p-2, 0x1.1fd834abca2e6p-56 }, 1 }, // tanf(0.40909090638160706) == 0.43355080589241020045 + { 0x1.ba2e8c0000000p-2, { 0x1.d7e21be7b824ep-2, 0x1.280c597324109p-58 }, 1 }, // tanf(0.4318181872367859) == 0.46082347490122266677 + { 0x1.d1745e0000000p-2, { 0x1.f466d760b947fp-2, 0x1.21b5240e6aa7ap-56 }, 1 }, // tanf(0.4545454680919647) == 0.48867355850081391394 + { 0x1.e8ba2e0000000p-2, { 0x1.08c7ca53ab12cp-1, -0x1.f57d7c1223293p-58 }, 1 }, // tanf(0.47727271914482117) == 0.51714927932110787298 + { 0x1.0000000000000p-1, { 0x1.17b4f5bf3474ap-1, 0x1.0c5e59201e209p-55 }, 1 }, // tanf(0.5) == 0.54630248984379051326 + { 0x1.0083120000000p-1, { 0x1.185f3da576451p-1, -0x1.886f12969f560p-55 }, 1 }, // tanf(0.5009999871253967) == 0.54760162968444532536 + { 0x1.1968ba0000000p-1, { 0x1.39a5b26fbb399p-1, 0x1.f18e65d72003dp-61 }, 1 }, // tanf(0.5496271252632141) == 0.61259229291828198955 + { 0x1.324e600000000p-1, { 0x1.5cf7a7b8a8dafp-1, 0x1.1199c7195a664p-56 }, 1 }, // tanf(0.5982542037963867) == 0.68157695893426319218 + { 0x1.4b34080000000p-1, { 0x1.82b608acdffb6p-1, -0x1.42d0e173a2fe0p-55 }, 1 }, // tanf(0.6468813419342041) == 0.75529505834855711174 + { 0x1.6419ae0000000p-1, { 0x1.ab55d23619846p-1, 0x1.c603f083e9a33p-55 }, 1 }, // tanf(0.6955084204673767) == 0.8346391383208889229 + { 0x1.7cff560000000p-1, { 0x1.d7663af1e2df4p-1, 0x1.7d485a7f8f1f9p-58 }, 1 }, // tanf(0.7441355586051941) == 0.92070182993614802475 + { 0x1.95e4fc0000000p-1, { 0x1.03cc749c072a3p+0, -0x1.7ecea077fdf39p-59 }, 1 }, // tanf(0.7927626371383667) == 1.0148384934356406957 + { 0x1.aecaa20000000p-1, { 0x1.1e66d51f99c48p+0, 0x1.f01ab7fb4bd0ep-56 }, 1 }, // tanf(0.8413897156715393) == 1.118756599631312936 + { 0x1.c7b04a0000000p-1, { 0x1.3c117f90d326cp+0, 0x1.03229ff72007ap-54 }, 1 }, // tanf(0.8900168538093567) == 1.2346420029236027667 + { 0x1.e095f00000000p-1, { 0x1.5d87230facb1cp+0, 0x1.f9a30159a1917p-54 }, 1 }, // tanf(0.9386439323425293) == 1.3653432763355289867 + { 0x1.f97b980000000p-1, { 0x1.83c017f3edf25p+0, -0x1.b4078f9456656p-56 }, 1 }, // tanf(0.9872710704803467) == 1.5146498652010873295 + { 0x1.0930a00000000p+0, { 0x1.b00e5d01af774p+0, 0x1.e3c0a7bf575a4p-54 }, 1 }, // tanf(1.035898208618164) == 1.6877191666712550938 + { 0x1.15a3720000000p+0, { 0x1.e44a7c100e5ccp+0, -0x1.b003b2f2f9540p-54 }, 1 }, // tanf(1.084525227546692) == 1.8917615451049297932 + { 0x1.2216460000000p+0, { 0x1.118f3c6a27a66p+1, 0x1.85e360e8ec4edp-58 }, 1 }, // tanf(1.1331523656845093) == 2.137183715661467259 + { 0x1.2e891a0000000p+0, { 0x1.38444381baf3ep+1, 0x1.991d471820d23p-53 }, 1 }, // tanf(1.1817795038223267) == 2.4395832427452710076 + { 0x1.3afbee0000000p+0, { 0x1.69672267c0dd2p+1, -0x1.d60d287c1a51cp-54 }, 1 }, // tanf(1.230406641960144) == 2.8234599119766493704 + { 0x1.476ec00000000p+0, { 0x1.aa316732a0df3p+1, 0x1.93f5fcaa8fa55p-53 }, 1 }, // tanf(1.2790336608886719) == 3.3296326634606374182 + { 0x1.53e1940000000p+0, { 0x1.02052da5ad457p+2, -0x1.f253167ebcf1fp-52 }, 1 }, // tanf(1.3276607990264893) == 4.0315660589158910495 + { 0x1.6054680000000p+0, { 0x1.44dfe8084e71bp+2, 0x1.85713a302a63dp-52 }, 1 }, // tanf(1.3762879371643066) == 5.0761661606900604407 + { 0x1.6cc73a0000000p+0, { 0x1.b398981d0788bp+2, 0x1.478f0a8738060p-53 }, 1 }, // tanf(1.4249149560928345) == 6.8061886104097865413 + { 0x1.793a0e0000000p+0, { 0x1.47ff19f0ecd5fp+3, 0x1.fdc0680466212p-51 }, 1 }, // tanf(1.4735420942306519) == 10.249890299374498244 + { 0x1.85ace20000000p+0, { 0x1.48c679186cc0bp+4, -0x1.a6980aa4df89ep-50 }, 1 }, // tanf(1.5221692323684692) == 20.548455329331810714 + { 0x1.921fb60000000p+0, { -0x1.5d14946dc9897p+24, -0x1.759086954a140p-30 }, 1 }, // tanf(1.5707963705062866) == -22877332.428856459874 + { 0x1.07e42a0000000p+5, { 0x1.8d4b1201a3a99p+11, -0x1.307422c8c1912p-45 }, 1 }, // tanf(32.98640823364258) == 3178.3459480473070133 + { 0x1.0e2cfc0000000p+5, { -0x1.001473484f3b0p+0, -0x1.a4e3909875188p-55 }, 1 }, // tanf(33.77196502685547) == -1.0003120471512652502 + { 0x1.1475cc0000000p+5, { -0x1.3ddbe01611c08p-20, 0x1.a01e80a914577p-74 }, 1 }, // tanf(34.557518005371094) == -1.1841166318736425066e-6 + { 0x1.1abe9e0000000p+5, { 0x1.0014a3d53c87ap+0, -0x1.4c3b82fae134ap-54 }, 1 }, // tanf(35.343074798583984) == 1.0003149409863269338 + { 0x1.21076e0000000p+5, { -0x1.904e6ea427870p+11, 0x1.4e728f4be16dcp-44 }, 1 }, // tanf(36.12862777709961) == -3202.4510060092942861 +}; + +#endif // defined(HAS_TANF) || defined(HAS_LIBM_SSE2) + +#if defined(HAS_TANF) + +void Test_tanf_approx(void) +{ + for (int i = 0; i < _countof(s_tanf_approx_tests); i++) + { + float x = s_tanf_approx_tests[i].x; + float expected = s_tanf_approx_tests[i].expected.rounded; + float z = tanf(x); + int64_t error = abs(ulp_error_flt(expected, z)); + ok(error <= s_tan_approx_tests[i].max_error, + "tan(%.6e) = %.7e, expected %.7e, error %I64d ULPs, max %u ULPs\n", + x, z, expected, error, s_tan_approx_tests[i].max_error); + } +} + +#endif // defined(HAS_TANF) + +#if defined(HAS_LIBM_SSE2) + +__ATTRIBUTE_SSE2__ __m128d __libm_sse2_tan(__m128d Xmm0); + +__ATTRIBUTE_SSE2__ +void Test_libm_sse2_tan(void) +{ + int i; + for (i = 0; i < _countof(s_tan_approx_tests); i++) + { + double x = s_tan_approx_tests[i].x; + double expected = s_tan_approx_tests[i].expected.rounded; + __m128d xmm0 = _mm_set_sd(x); + __m128d xmm1 = __libm_sse2_tan(xmm0); + double z = _mm_cvtsd_f64(xmm1); + int64_t error = ulp_error_precise(&s_tan_approx_tests[i].expected, z); + ok(error <= s_tan_approx_tests[i].max_error, + "__libm_sse2_tan(%.17e) = %.17e, expected %.17e, error %I64d ULPs, max %u ULPs\n", + x, z, expected, error, s_tan_approx_tests[i].max_error); + } +} + +__ATTRIBUTE_SSE2__ __m128 __libm_sse2_tanf(__m128 Xmm0); + +__ATTRIBUTE_SSE2__ +void Test_libm_sse2_tanf(void) +{ + int i; + for (i = 0; i < _countof(s_tanf_approx_tests); i++) + { + float x = s_tanf_approx_tests[i].x; + float expected = s_tanf_approx_tests[i].expected.rounded; + __m128 xmm0 = _mm_set_ps1(x); + __m128 xmm1 = __libm_sse2_tanf(xmm0); + float z = _mm_cvtss_f32(xmm1); + int64_t error = ulp_error_flt(expected, z); + ok(error <= s_tanf_approx_tests[i].max_error, + "__libm_sse2_tanf(%.6e) = %.7e, expected %.7e, error %I64d ULPs, max %u ULPs\n", + x, z, expected, error, s_tanf_approx_tests[i].max_error); + } +} + +#endif // defined(HAS_LIBM_SSE2) + +START_TEST(tan) +{ + Test_tan_exact(); + Test_tan_approx(); +#if defined(HAS_TANF) + Test_tanf_exact(); + Test_tanf_approx(); +#endif +#if defined(HAS_LIBM_SSE2) + Test_libm_sse2_tan(); + Test_libm_sse2_tanf(); +#endif +} diff --git a/modules/rostests/apitests/msvcrt/CMakeLists.txt b/modules/rostests/apitests/msvcrt/CMakeLists.txt index 05443792aba..2832d5fdf66 100644 --- a/modules/rostests/apitests/msvcrt/CMakeLists.txt +++ b/modules/rostests/apitests/msvcrt/CMakeLists.txt @@ -42,6 +42,7 @@ list(APPEND SOURCE_CRT_TESTS ../crt/strlen.c ../crt/strtoul.c ../crt/system.c + ../crt/tan.c ../crt/wcstombs.c ../crt/wcstoul.c ../crt/wctomb.c diff --git a/modules/rostests/apitests/msvcrt/testlist.c b/modules/rostests/apitests/msvcrt/testlist.c index b617d82cec4..92cc41b2dea 100644 --- a/modules/rostests/apitests/msvcrt/testlist.c +++ b/modules/rostests/apitests/msvcrt/testlist.c @@ -38,6 +38,7 @@ extern void func_strcpy(void); extern void func_strlen(void); extern void func_strtoul(void); extern void func_system(void); +extern void func_tan(void); extern void func_wcstombs(void); extern void func_wcstoul(void); extern void func_wctomb(void); @@ -90,6 +91,7 @@ const struct test winetest_testlist[] = { "strlen", func_strlen }, { "strtoul", func_strtoul }, { "system", func_system }, + { "tan", func_tan }, { "wcstombs", func_wcstombs }, { "wcstoul", func_wcstoul }, { "wctomb", func_wctomb }, diff --git a/modules/rostests/apitests/ucrtbase/CMakeLists.txt b/modules/rostests/apitests/ucrtbase/CMakeLists.txt index 36e7dd91d55..74ec6120547 100644 --- a/modules/rostests/apitests/ucrtbase/CMakeLists.txt +++ b/modules/rostests/apitests/ucrtbase/CMakeLists.txt @@ -22,6 +22,7 @@ list(APPEND SOURCE ../crt/round.c ../crt/sin.c ../crt/sqrt.c + ../crt/tan.c testlist.c ) diff --git a/modules/rostests/apitests/ucrtbase/testlist.c b/modules/rostests/apitests/ucrtbase/testlist.c index a5032fd7900..cae500ea054 100644 --- a/modules/rostests/apitests/ucrtbase/testlist.c +++ b/modules/rostests/apitests/ucrtbase/testlist.c @@ -14,6 +14,7 @@ extern void func_log10(void); extern void func_round(void); extern void func_sin(void); extern void func_sqrt(void); +extern void func_tan(void); const struct test winetest_testlist[] = @@ -29,6 +30,7 @@ const struct test winetest_testlist[] = { "round", func_round }, { "sin", func_sin }, { "sqrt", func_sqrt }, + { "tan", func_tan }, { 0, 0 } };