1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143 |
- // (C) Copyright John Maddock 2016.
- // Use, modification and distribution are subject to the
- // Boost Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifdef _MSC_VER
- #pragma warning(disable : 4127) // conditional expression is constant
- #endif
- #if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_CPP_DEC_FLOAT_2) && !defined(TEST_CPP_DEC_FLOAT_3) && !defined(TEST_CPP_DEC_FLOAT_4) && !defined(TEST_CPP_DEC_FLOAT_5) && !defined(TEST_CPP_DEC_FLOAT_6) && !defined(TEST_CPP_BIN_FLOAT_2) && !defined(TEST_CPP_BIN_FLOAT_3)
- #define TEST_MPF_50
- #define TEST_MPFR_50
- #define TEST_MPFI_50
- #define TEST_CPP_DEC_FLOAT
- #define TEST_CPP_DEC_FLOAT_2
- #define TEST_CPP_DEC_FLOAT_3
- #define TEST_CPP_DEC_FLOAT_4
- #define TEST_CPP_DEC_FLOAT_5
- #define TEST_CPP_DEC_FLOAT_6
- #define TEST_FLOAT128
- #define TEST_CPP_BIN_FLOAT
- #define TEST_CPP_BIN_FLOAT_2
- #define TEST_CPP_BIN_FLOAT_3
- #ifdef _MSC_VER
- #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
- #endif
- #ifdef __GNUC__
- #pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
- #endif
- #endif
- #if defined(TEST_MPF_50)
- #include <boost/multiprecision/gmp.hpp>
- #endif
- #ifdef TEST_MPFR_50
- #include <boost/multiprecision/mpfr.hpp>
- #endif
- #ifdef TEST_MPFI_50
- #include <boost/multiprecision/mpfi.hpp>
- #endif
- #if defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_DEC_FLOAT_2) || defined(TEST_CPP_DEC_FLOAT_3) || defined(TEST_CPP_DEC_FLOAT_4) || defined(TEST_CPP_DEC_FLOAT_5) || defined(TEST_CPP_DEC_FLOAT_6)
- #include <boost/multiprecision/cpp_dec_float.hpp>
- #endif
- #if defined(TEST_CPP_BIN_FLOAT) || defined(TEST_CPP_BIN_FLOAT_2) || defined(TEST_CPP_BIN_FLOAT_3)
- #include <boost/multiprecision/cpp_bin_float.hpp>
- #include <boost/multiprecision/debug_adaptor.hpp>
- #endif
- #ifdef TEST_FLOAT128
- #include <boost/multiprecision/float128.hpp>
- #endif
- #include <boost/math/constants/constants.hpp>
- #include <boost/math/special_functions/gamma.hpp>
- #include "test.hpp"
- #ifdef signbit
- #undef signbit
- #endif
- #ifdef sign
- #undef sign
- #endif
- #ifdef changesign
- #undef changesign
- #endif
- #ifdef copysign
- #undef copysign
- #endif
- #ifdef fpclassify
- #undef fpclassify
- #endif
- #ifdef isinf
- #undef isinf
- #endif
- #ifdef isnan
- #undef isnan
- #endif
- #ifdef isnormal
- #undef isnormal
- #endif
- #ifdef MPFR_VERSION_MAJOR
- #define BOOST_MPFR_VERSION MPFR_VERSION_MAJOR * 10000 + MPFR_VERSION_MINOR * 100 + MPFR_VERSION_PATCHLEVEL
- #endif
- template <class T, class U>
- void test_less(T a, U b)
- {
- BOOST_CHECK(a < b);
- BOOST_CHECK(a <= b);
- BOOST_CHECK(!(a > b));
- BOOST_CHECK(!(a >= b));
- BOOST_CHECK(!(a == b));
- BOOST_CHECK((a != b));
- BOOST_CHECK(b > a);
- BOOST_CHECK(b >= a);
- BOOST_CHECK(!(b < a));
- BOOST_CHECK(!(b <= a));
- BOOST_CHECK(!(b == a));
- BOOST_CHECK((b != a));
- BOOST_CHECK(isless(a, b));
- BOOST_CHECK(islessequal(a, b));
- BOOST_CHECK(!isgreater(a, b));
- BOOST_CHECK(!isgreaterequal(a, b));
- BOOST_CHECK(islessgreater(a, b));
- BOOST_CHECK(!isless(b, a));
- BOOST_CHECK(!islessequal(b, a));
- BOOST_CHECK(isgreater(b, a));
- BOOST_CHECK(isgreaterequal(b, a));
- BOOST_CHECK(islessgreater(b, a));
- }
- template <class T, class U>
- void test_equal(T a, U b)
- {
- BOOST_CHECK(!(a < b));
- BOOST_CHECK(a <= b);
- BOOST_CHECK(!(a > b));
- BOOST_CHECK((a >= b));
- BOOST_CHECK((a == b));
- BOOST_CHECK(!(a != b));
- BOOST_CHECK(!(b > a));
- BOOST_CHECK(b >= a);
- BOOST_CHECK(!(b < a));
- BOOST_CHECK((b <= a));
- BOOST_CHECK((b == a));
- BOOST_CHECK(!(b != a));
- BOOST_CHECK(!isless(a, b));
- BOOST_CHECK(islessequal(a, b));
- BOOST_CHECK(!isgreater(a, b));
- BOOST_CHECK(isgreaterequal(a, b));
- BOOST_CHECK(!islessgreater(a, b));
- BOOST_CHECK(!isless(b, a));
- BOOST_CHECK(islessequal(b, a));
- BOOST_CHECK(!isgreater(b, a));
- BOOST_CHECK(isgreaterequal(b, a));
- BOOST_CHECK(!islessgreater(b, a));
- }
- template <class T, class U>
- void test_unordered(T a, U b)
- {
- BOOST_CHECK(!(a < b));
- BOOST_CHECK(!(a <= b));
- BOOST_CHECK(!(a > b));
- BOOST_CHECK(!(a >= b));
- BOOST_CHECK(!(a == b));
- BOOST_CHECK((a != b));
- BOOST_CHECK(!(b > a));
- BOOST_CHECK(!(b >= a));
- BOOST_CHECK(!(b < a));
- BOOST_CHECK(!(b <= a));
- BOOST_CHECK(!(b == a));
- BOOST_CHECK((b != a));
- BOOST_CHECK(!isless(a, b));
- BOOST_CHECK(!islessequal(a, b));
- BOOST_CHECK(!isgreater(a, b));
- BOOST_CHECK(!isgreaterequal(a, b));
- BOOST_CHECK(!islessgreater(a, b));
- BOOST_CHECK(!isless(b, a));
- BOOST_CHECK(!islessequal(b, a));
- BOOST_CHECK(!isgreater(b, a));
- BOOST_CHECK(!isgreaterequal(b, a));
- BOOST_CHECK(!islessgreater(b, a));
- }
- template <class T>
- void test()
- {
- //
- // Basic sanity checks for C99 functions which are just imported versions
- // from Boost.Math. These should still be found via ADL so no using declarations here...
- //
- T val = 2;
- BOOST_CHECK(signbit(val) == 0);
- BOOST_CHECK(signbit(val + 2) == 0);
- val = -val;
- BOOST_CHECK(signbit(val));
- BOOST_CHECK(signbit(val * 2));
- val = 2;
- BOOST_CHECK_EQUAL(sign(val), 1);
- BOOST_CHECK_EQUAL(sign(val + 2), 1);
- val = -val;
- BOOST_CHECK_EQUAL(sign(val), -1);
- BOOST_CHECK_EQUAL(sign(val * 2), -1);
- val = 0;
- BOOST_CHECK_EQUAL(sign(val), 0);
- BOOST_CHECK_EQUAL(sign(val * 2), 0);
- val = 2;
- BOOST_CHECK_EQUAL(changesign(val), -2);
- BOOST_CHECK_EQUAL(changesign(val * 2), -4);
- val = -2;
- BOOST_CHECK_EQUAL(changesign(val), 2);
- BOOST_CHECK_EQUAL(changesign(val * 2), 4);
- val = 0;
- BOOST_CHECK_EQUAL(changesign(val), 0);
- BOOST_CHECK_EQUAL(changesign(val * 2), 0);
- // Things involving signed zero, need to detect it first:
- T neg_zero_test = -(std::numeric_limits<T>::min)();
- neg_zero_test /= (std::numeric_limits<T>::max)();
- T one(1);
- bool test_signed_zero = !boost::multiprecision::is_interval_number<T>::value && std::numeric_limits<T>::has_infinity && (one / neg_zero_test < 0);
- if (test_signed_zero)
- {
- BOOST_CHECK(signbit(changesign(val)));
- BOOST_CHECK(signbit(changesign(val * 2)));
- }
- T s = 2;
- val = 3;
- BOOST_CHECK_EQUAL(copysign(val, s), 3);
- BOOST_CHECK_EQUAL(copysign(val, s * -2), -3);
- BOOST_CHECK_EQUAL(copysign(-2 * val, s), 6);
- BOOST_CHECK_EQUAL(copysign(-2 * val, 2 * s), 6);
- s = -2;
- BOOST_CHECK_EQUAL(copysign(val, s), -3);
- BOOST_CHECK_EQUAL(copysign(val, s * -2), 3);
- BOOST_CHECK_EQUAL(copysign(-2 * val, s), -6);
- BOOST_CHECK_EQUAL(copysign(-2 * val, 2 * s), -6);
- val = -3;
- BOOST_CHECK_EQUAL(copysign(val, s), -3);
- BOOST_CHECK_EQUAL(copysign(val, s * -2), 3);
- BOOST_CHECK_EQUAL(copysign(-2 * val, s), -6);
- BOOST_CHECK_EQUAL(copysign(-2 * val, 2 * s), -6);
- s = 0;
- BOOST_CHECK_EQUAL(copysign(val, s), 3);
- // Things involving signed zero, need to detect it first:
- if (test_signed_zero)
- {
- BOOST_CHECK_EQUAL(copysign(val, s * -2), -3);
- }
- BOOST_CHECK_EQUAL(copysign(-2 * val, s), 6);
- BOOST_CHECK_EQUAL(copysign(-2 * val, 2 * s), 6);
- // Things involving signed zero, need to detect it first:
- if (test_signed_zero)
- {
- s = changesign(s);
- if (signbit(s))
- {
- BOOST_CHECK_EQUAL(copysign(val, s), -3);
- BOOST_CHECK_EQUAL(copysign(val, s * -2), 3);
- BOOST_CHECK_EQUAL(copysign(-2 * val, s), -6);
- BOOST_CHECK_EQUAL(copysign(-2 * val, 2 * s), -6);
- }
- }
- val = 3;
- BOOST_CHECK_EQUAL(fpclassify(val), FP_NORMAL);
- BOOST_CHECK_EQUAL(fpclassify(val * 3), FP_NORMAL);
- BOOST_CHECK(!isinf(val));
- BOOST_CHECK(!isinf(val + 2));
- BOOST_CHECK(!isnan(val));
- BOOST_CHECK(!isnan(val + 2));
- BOOST_CHECK(isnormal(val));
- BOOST_CHECK(isnormal(val + 2));
- val = -3;
- BOOST_CHECK_EQUAL(fpclassify(val), FP_NORMAL);
- BOOST_CHECK_EQUAL(fpclassify(val * 3), FP_NORMAL);
- BOOST_CHECK(!isinf(val));
- BOOST_CHECK(!isinf(val + 2));
- BOOST_CHECK(!isnan(val));
- BOOST_CHECK(!isnan(val + 2));
- BOOST_CHECK(isnormal(val));
- BOOST_CHECK(isnormal(val + 2));
- val = 0;
- BOOST_CHECK_EQUAL(fpclassify(val), FP_ZERO);
- BOOST_CHECK_EQUAL(fpclassify(val * 3), FP_ZERO);
- BOOST_CHECK(!isinf(val));
- BOOST_CHECK(!isinf(val + 2));
- BOOST_CHECK(!isnan(val));
- BOOST_CHECK(!isnan(val + 2));
- BOOST_CHECK(!isnormal(val));
- BOOST_CHECK(!isnormal(val * 2));
- BOOST_CHECK(!isnormal(val * -2));
- if (std::numeric_limits<T>::has_infinity)
- {
- val = std::numeric_limits<T>::infinity();
- BOOST_CHECK_EQUAL(fpclassify(val), FP_INFINITE);
- BOOST_CHECK_EQUAL(fpclassify(val * 3), FP_INFINITE);
- BOOST_CHECK(isinf(val));
- BOOST_CHECK(isinf(val + 2));
- BOOST_CHECK(!isnan(val));
- BOOST_CHECK(!isnan(val + 2));
- BOOST_CHECK(!isnormal(val));
- BOOST_CHECK(!isnormal(val + 2));
- val = -val;
- BOOST_CHECK_EQUAL(fpclassify(val), FP_INFINITE);
- BOOST_CHECK_EQUAL(fpclassify(val * 3), FP_INFINITE);
- BOOST_CHECK(isinf(val));
- BOOST_CHECK(isinf(val + 2));
- BOOST_CHECK(!isnan(val));
- BOOST_CHECK(!isnan(val + 2));
- BOOST_CHECK(!isnormal(val));
- BOOST_CHECK(!isnormal(val + 2));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- val = std::numeric_limits<T>::quiet_NaN();
- BOOST_CHECK_EQUAL(fpclassify(val), FP_NAN);
- BOOST_CHECK_EQUAL(fpclassify(val * 3), FP_NAN);
- BOOST_CHECK(!isinf(val));
- BOOST_CHECK(!isinf(val + 2));
- BOOST_CHECK(isnan(val));
- BOOST_CHECK(isnan(val + 2));
- BOOST_CHECK(!isnormal(val));
- BOOST_CHECK(!isnormal(val + 2));
- }
- s = 8 * std::numeric_limits<T>::epsilon();
- val = 2.5;
- BOOST_CHECK_CLOSE_FRACTION(asinh(val), T("1.6472311463710957106248586104436196635044144301932365282203100930843983757633104078778420255069424907777006132075516484778755360595913172299093829522950397895699619540523579875476513967578478619028438291006578604823887119907434"), s);
- BOOST_CHECK_CLOSE_FRACTION(asinh(val + T(0)), T("1.6472311463710957106248586104436196635044144301932365282203100930843983757633104078778420255069424907777006132075516484778755360595913172299093829522950397895699619540523579875476513967578478619028438291006578604823887119907434"), s);
- BOOST_CHECK_CLOSE_FRACTION(acosh(val), T("1.5667992369724110786640568625804834938620823510926588639329459980122148134693922696279968499622201141051039184050936311066453565386393240356562374302417843319480223211857615778787272615171906055455922537080327062362258846337050"), s);
- BOOST_CHECK_CLOSE_FRACTION(acosh(val + T(0)), T("1.5667992369724110786640568625804834938620823510926588639329459980122148134693922696279968499622201141051039184050936311066453565386393240356562374302417843319480223211857615778787272615171906055455922537080327062362258846337050"), s);
- val = 0.5;
- BOOST_CHECK_CLOSE_FRACTION(atanh(val), T("0.5493061443340548456976226184612628523237452789113747258673471668187471466093044834368078774068660443939850145329789328711840021129652599105264009353836387053015813845916906835896868494221804799518712851583979557605727959588753"), s);
- BOOST_CHECK_CLOSE_FRACTION(atanh(val + T(0)), T("0.5493061443340548456976226184612628523237452789113747258673471668187471466093044834368078774068660443939850145329789328711840021129652599105264009353836387053015813845916906835896868494221804799518712851583979557605727959588753"), s);
- val = 55.25;
- BOOST_CHECK_CLOSE_FRACTION(cbrt(val), T("3.8087058015466360309383876359583281382991983919300128125378938779672144843676192684301168479657279498120767424724024965319869248797423276064015643361426189576415670917818313417529572608229017809069355688606687557031643655896118"), s);
- BOOST_CHECK_CLOSE_FRACTION(cbrt(val + T(0)), T("3.8087058015466360309383876359583281382991983919300128125378938779672144843676192684301168479657279498120767424724024965319869248797423276064015643361426189576415670917818313417529572608229017809069355688606687557031643655896118"), s);
- if (!boost::multiprecision::is_interval_number<T>::value)
- {
- val = 2.75;
- BOOST_CHECK_CLOSE_FRACTION(erf(val), T("0.9998993780778803631630956080249130432349352621422640655161095794654526422025908961447328296681056892975214344779300734620255391682713519265048496199034963706976420982849598189071465666866369396765001072187538732800143945532487"), s);
- BOOST_CHECK_CLOSE_FRACTION(erf(val + T(0)), T("0.9998993780778803631630956080249130432349352621422640655161095794654526422025908961447328296681056892975214344779300734620255391682713519265048496199034963706976420982849598189071465666866369396765001072187538732800143945532487"), s);
- BOOST_CHECK_CLOSE_FRACTION(erfc(val), T("0.0001006219221196368369043919750869567650647378577359344838904205345473577974091038552671703318943107024785655220699265379744608317286480734951503800965036293023579017150401810928534333133630603234998927812461267199856054467512"), s);
- BOOST_CHECK_CLOSE_FRACTION(erfc(val + T(0)), T("0.0001006219221196368369043919750869567650647378577359344838904205345473577974091038552671703318943107024785655220699265379744608317286480734951503800965036293023579017150401810928534333133630603234998927812461267199856054467512"), s);
- }
- val = 0.125;
- BOOST_CHECK_CLOSE_FRACTION(expm1(val), T("0.1331484530668263168290072278117938725655031317451816259128200360788235778800483865139399907949417285732315270156473075657048210452584733998785564025916995261162759280700397984729320345630340659469435372721057879969170503978449"), s);
- BOOST_CHECK_CLOSE_FRACTION(expm1(val + T(0)), T("0.1331484530668263168290072278117938725655031317451816259128200360788235778800483865139399907949417285732315270156473075657048210452584733998785564025916995261162759280700397984729320345630340659469435372721057879969170503978449"), s);
- val = 20;
- s = 2;
- BOOST_CHECK_EQUAL(fdim(val, s), 18);
- BOOST_CHECK_EQUAL(fdim(s, val), 0);
- BOOST_CHECK_EQUAL(fdim(val, s * 2), 16);
- BOOST_CHECK_EQUAL(fdim(s * 2, val), 0);
- BOOST_CHECK_EQUAL(fdim(val, 2), 18);
- BOOST_CHECK_EQUAL(fdim(2, val), 0);
- BOOST_CHECK_EQUAL(fmax(val, s), val);
- BOOST_CHECK_EQUAL(fmax(s, val), val);
- BOOST_CHECK_EQUAL(fmax(val * 2, s), val * 2);
- BOOST_CHECK_EQUAL(fmax(val, s * 2), val);
- BOOST_CHECK_EQUAL(fmax(val * 2, s * 2), val * 2);
- BOOST_CHECK_EQUAL(fmin(val, s), s);
- BOOST_CHECK_EQUAL(fmin(s, val), s);
- BOOST_CHECK_EQUAL(fmin(val * 2, s), s);
- BOOST_CHECK_EQUAL(fmin(val, s * 2), s * 2);
- BOOST_CHECK_EQUAL(fmin(val * 2, s * 2), s * 2);
- BOOST_CHECK_EQUAL(fmax(val, 2), val);
- BOOST_CHECK_EQUAL(fmax(val, 2.0), val);
- BOOST_CHECK_EQUAL(fmax(20, s), val);
- BOOST_CHECK_EQUAL(fmax(20.0, s), val);
- BOOST_CHECK_EQUAL(fmin(val, 2), s);
- BOOST_CHECK_EQUAL(fmin(val, 2.0), s);
- BOOST_CHECK_EQUAL(fmin(20, s), s);
- BOOST_CHECK_EQUAL(fmin(20.0, s), s);
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- BOOST_CHECK_EQUAL(fmax(val, std::numeric_limits<T>::quiet_NaN()), val);
- BOOST_CHECK_EQUAL(fmax(std::numeric_limits<T>::quiet_NaN(), val), val);
- BOOST_CHECK_EQUAL(fmin(val, std::numeric_limits<T>::quiet_NaN()), val);
- BOOST_CHECK_EQUAL(fmin(std::numeric_limits<T>::quiet_NaN(), val), val);
- }
- if (std::numeric_limits<double>::has_quiet_NaN)
- {
- BOOST_CHECK_EQUAL(fmax(val, std::numeric_limits<double>::quiet_NaN()), val);
- BOOST_CHECK_EQUAL(fmax(std::numeric_limits<double>::quiet_NaN(), val), val);
- BOOST_CHECK_EQUAL(fmin(val, std::numeric_limits<double>::quiet_NaN()), val);
- BOOST_CHECK_EQUAL(fmin(std::numeric_limits<double>::quiet_NaN(), val), val);
- }
- test_less(s, val);
- test_less(2, val);
- test_less(s, 20);
- test_less(s + 0, val);
- test_less(s, val * 1);
- test_less(s * 1, val * 1);
- test_less(s * 1, 20);
- test_less(s + 2, val * 2);
- test_equal(val, val);
- test_equal(20, val);
- test_equal(val, 20);
- test_equal(val + 0, val);
- test_equal(val, val * 1);
- test_equal(val * 1, val * 1);
- test_equal(val * 1, 20);
- test_equal(val * 20, val * 20);
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- s = std::numeric_limits<T>::quiet_NaN();
- test_unordered(s, val);
- test_unordered(s, 20);
- test_unordered(s + 0, val);
- test_unordered(s, val * 1);
- test_unordered(s * 1, val * 1);
- test_unordered(s * 1, 20);
- test_unordered(s + 2, val * 2);
- if (std::numeric_limits<double>::has_quiet_NaN)
- {
- double n = std::numeric_limits<double>::quiet_NaN();
- test_unordered(n, val);
- }
- }
- T tol = 8 * std::numeric_limits<T>::epsilon();
- s = 2;
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(val, s)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(val, 2)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(val, 2.0)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(20, s)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(20.0, s)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(val * 1, s)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(val * 1, s * 1)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(val * 1, 2)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(val * 1, 2.0)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(20, s * 1)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(hypot(20.0, s * 1)), T("20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530"), tol);
- BOOST_CHECK_CLOSE_FRACTION(lgamma(val), T("39.339884187199494036224652394567381081691457206897853119937969989377572554993874476249340525204204720861169039582"), tol);
- BOOST_CHECK_CLOSE_FRACTION(lgamma(val + 0), T("39.339884187199494036224652394567381081691457206897853119937969989377572554993874476249340525204204720861169039582"), tol);
- BOOST_CHECK_EQUAL(lrint(val), 20);
- BOOST_CHECK_EQUAL(lrint(val * 2), 40);
- BOOST_CHECK_EQUAL(llrint(val), 20);
- BOOST_CHECK_EQUAL(llrint(val * 2), 40);
- val = 0.125;
- BOOST_CHECK_CLOSE_FRACTION(log1p(val), T("0.117783035656383454538794109470521705068480712564733141107348638794807720528133786929641528638208114949935615070"), tol);
- BOOST_CHECK_CLOSE_FRACTION(log1p(val + 0), T("0.117783035656383454538794109470521705068480712564733141107348638794807720528133786929641528638208114949935615070"), tol);
- val = 20;
- BOOST_CHECK_CLOSE_FRACTION(T(log2(val)), T("4.321928094887362347870319429489390175864831393024580612054756395815934776608625215850139743359370155099657371710"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(log2(val + 0)), T("4.321928094887362347870319429489390175864831393024580612054756395815934776608625215850139743359370155099657371710"), tol);
- BOOST_CHECK_EQUAL(T(nearbyint(val)), 20);
- BOOST_CHECK_EQUAL(T(nearbyint(val + 0.25)), 20);
- BOOST_CHECK_EQUAL(T(rint(val)), 20);
- BOOST_CHECK_EQUAL(T(rint(val + 0.25)), 20);
- BOOST_CHECK_GT(nextafter(val, T(200)), val);
- BOOST_CHECK_GT(nextafter(val + 0, T(200)), val);
- BOOST_CHECK_GT(nextafter(val + 0, T(200) + 1), val);
- BOOST_CHECK_GT(nextafter(val, T(200) + 1), val);
- BOOST_CHECK_GT(nexttoward(val, T(200)), val);
- BOOST_CHECK_GT(nexttoward(val + 0, T(200)), val);
- BOOST_CHECK_GT(nexttoward(val + 0, T(200) + 1), val);
- BOOST_CHECK_GT(nexttoward(val, T(200) + 1), val);
- val = 21;
- s = 5;
- BOOST_CHECK_EQUAL(T(remainder(val, s)), 1);
- BOOST_CHECK_EQUAL(T(remainder(val, 5)), 1);
- BOOST_CHECK_EQUAL(T(remainder(21, s)), 1);
- BOOST_CHECK_EQUAL(T(remainder(val * 1, s)), 1);
- BOOST_CHECK_EQUAL(T(remainder(val * 1, s * 1)), 1);
- BOOST_CHECK_EQUAL(T(remainder(val, s * 1)), 1);
- BOOST_CHECK_EQUAL(T(remainder(val * 1, 5)), 1);
- BOOST_CHECK_EQUAL(T(remainder(21, s * 1)), 1);
- int i(0);
- BOOST_CHECK_EQUAL(T(remquo(val, s, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- BOOST_CHECK_EQUAL(T(remquo(val, 5, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- BOOST_CHECK_EQUAL(T(remquo(21, s, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- BOOST_CHECK_EQUAL(T(remquo(val * 1, s, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- BOOST_CHECK_EQUAL(T(remquo(val * 1, s * 1, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- BOOST_CHECK_EQUAL(T(remquo(val, s * 1, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- BOOST_CHECK_EQUAL(T(remquo(val * 1, 5, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- BOOST_CHECK_EQUAL(T(remquo(21, s * 1, &i)), 1);
- BOOST_CHECK_EQUAL(i, 4);
- i = 0;
- val = 5.25;
- tol = 3000;
- BOOST_CHECK_CLOSE_FRACTION(tgamma(val), T("35.211611852799685705225257690531248115026311138908448314086859575901217653313145619623624570033258659272301335544"), tol);
- BOOST_CHECK_CLOSE_FRACTION(tgamma(val + 1), T("184.86096222719834995243260287528905260388813347926935364895601277348139267989401450302402899267460796117958201160"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(exp2(val)), T("38.054627680087074134959999057935229289375106958842157216608071191022933383261349115865003025220405558913196632792"), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(exp2(val + 1)), T("76.109255360174148269919998115870458578750213917684314433216142382045866766522698231730006050440811117826393265585"), tol);
- val = 15;
- BOOST_CHECK_CLOSE_FRACTION(T(exp2(val)), T(32768uL), tol);
- BOOST_CHECK_CLOSE_FRACTION(T(exp2(val + 1)), T(65536uL), tol);
- i = fpclassify(val) + isgreaterequal(val, s) + islessequal(val, s) + isnan(val) + isunordered(val, s) + isfinite(val) + isinf(val) + islessgreater(val, s) + isnormal(val) + signbit(val) + isgreater(val, s) + isless(val, s);
- }
- template <class T>
- void test_poison()
- {
- // use these macros as proxies for determining C99 support:
- #if defined(FP_ILOGB0) && defined(FP_INFINITE)
- //
- // These tests verify that our function overloads for Boost.Multiprecision
- // don't do anything nasty to the std:: overloads for built in types:
- //
- using namespace std;
- using namespace boost::multiprecision;
- //using namespace boost::math;
- T a(2), b(0.3f), c(4), result(0);
- int i;
- result += abs(a);
- result += cosh(a);
- result += fmod(a, b);
- result += logb(a);
- result += remquo(a, b, &i);
- result += acos(b);
- result += erf(a);
- result += frexp(a, &i);
- result += lrint(a);
- result += rint(a);
- result += acosh(b);
- result += erfc(b);
- result += hypot(a, b);
- result += lround(c);
- result += round(c);
- result += asin(b);
- result += exp2(a);
- result += ilogb(b);
- result += modf(a, &b);
- result += scalbln(a, i);
- result += asinh(b);
- result += exp(b);
- result += ldexp(a, i);
- result += scalbn(a, i);
- result += atan(b);
- result += expm1(a);
- result += lgamma(a);
- result += sin(b);
- result += atan2(a, c);
- result += fabs(a);
- result += llrint(a);
- result += sinh(b);
- result += atanh(b);
- result += fdim(a, b);
- result += llround(a);
- result += nearbyint(a);
- result += sqrt(b);
- result += cbrt(a);
- result += floor(b);
- result += log(a);
- result += nextafter(a, b);
- result += tan(b);
- result += ceil(b);
- result += fma(a, b, c);
- result += log10(a);
- result += nexttoward(a, b);
- result += tanh(a);
- result += copysign(a, b);
- result += fmax(a, b);
- result += log1p(a);
- result += pow(a, b);
- result += tgamma(a);
- result += cos(b);
- result += fmin(a, b);
- result += log2(a);
- result += remainder(a, b);
- result += trunc(b);
- result += (min)(a, b);
- result += (max)(a, b);
- #if !BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 60000)
- i = fpclassify(a) + isgreaterequal(a, b) + islessequal(a, b) + isnan(a) + isunordered(a, b) + isfinite(a) + isinf(a) + islessgreater(a, b) + isnormal(a) + signbit(a) + isgreater(a, b) + isless(a, b);
- #endif
- #endif
- }
- template <class T>
- bool type_sets_errno(const T&)
- {
- return true;
- }
- #ifdef TEST_MPFR_50
- template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
- bool type_sets_errno(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>&)
- {
- return false;
- }
- #endif
- #ifdef TEST_FLOAT128
- bool type_sets_errno(const boost::multiprecision::float128&)
- {
- return false;
- }
- #endif
- template <class T>
- typename boost::enable_if_c<std::numeric_limits<T>::is_specialized>::type check_invalid(const T& val)
- {
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- BOOST_CHECK(isnan(val));
- }
- else
- {
- BOOST_CHECK_EQUAL(val, 0);
- }
- if (type_sets_errno(val))
- BOOST_CHECK_EQUAL(errno, EDOM);
- errno = 0;
- }
- template <class T>
- typename boost::disable_if_c<std::numeric_limits<T>::is_specialized>::type check_invalid(const T& val)
- {
- check_invalid(static_cast<typename T::result_type>(val));
- }
- template <class T>
- void check_erange(const T& val)
- {
- if (type_sets_errno(val))
- BOOST_CHECK_EQUAL(errno, ERANGE);
- errno = 0;
- }
- template <class T>
- void test_c99_appendix_F()
- {
- //
- // Tests conformance to non-normative appendix F.9.1 of C99, basically how to handle
- // special cases, infinities and NaN's.
- //
- errno = 0;
- T tol = std::numeric_limits<T>::epsilon();
- // F.9.1.1:
- T arg = 1;
- T val = acos(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = 2;
- check_invalid(acos(arg));
- arg = -2;
- check_invalid(acos(arg));
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- check_invalid(acos(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(acos(arg));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(acos(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(acos(arg));
- }
- // F.9.1.2:
- arg = 0;
- val = asin(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = asin(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- arg = 2;
- check_invalid(asin(arg));
- arg = -2;
- check_invalid(asin(arg));
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- check_invalid(asin(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(asin(arg));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(asin(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(asin(arg));
- }
- // F.9.1.3:
- arg = 0;
- val = atan(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = atan(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = atan(arg);
- BOOST_CHECK_EQUAL(val, boost::math::constants::half_pi<T>());
- arg = -std::numeric_limits<T>::infinity();
- val = atan(arg);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::half_pi<T>());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(asin(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(asin(arg));
- }
- // F.9.1.4:
- arg = 0;
- T arg2 = 0;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- arg2 = -arg2;
- if (signbit(arg2))
- {
- arg = 0;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, boost::math::constants::pi<T>());
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::pi<T>());
- BOOST_CHECK(signbit(val));
- }
- arg = 0;
- arg2 = -2;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, boost::math::constants::pi<T>());
- arg = -arg;
- if (signbit(arg))
- {
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::pi<T>());
- }
- arg = 0;
- arg2 = 2;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- arg = -2;
- arg2 = 0;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::half_pi<T>());
- arg2 = -arg2;
- if (signbit(arg2))
- {
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::half_pi<T>());
- }
- arg = 2;
- arg2 = 0;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, boost::math::constants::half_pi<T>());
- arg2 = -arg2;
- if (signbit(arg2))
- {
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, boost::math::constants::half_pi<T>());
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 2;
- arg2 = -std::numeric_limits<T>::infinity();
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, boost::math::constants::pi<T>());
- arg = -arg;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::pi<T>());
- arg = 2;
- arg2 = std::numeric_limits<T>::infinity();
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(-T(0)))
- {
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- arg = std::numeric_limits<T>::infinity();
- arg2 = 2;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, boost::math::constants::half_pi<T>());
- arg = -arg;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::half_pi<T>());
- arg = std::numeric_limits<T>::infinity();
- arg2 = -2;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, boost::math::constants::half_pi<T>());
- arg = -arg;
- val = atan2(arg, arg2);
- BOOST_CHECK_EQUAL(val, -boost::math::constants::half_pi<T>());
- arg = std::numeric_limits<T>::infinity();
- arg2 = -std::numeric_limits<T>::infinity();
- val = atan2(arg, arg2);
- BOOST_CHECK_CLOSE_FRACTION(val, boost::math::constants::three_quarters_pi<T>(), tol);
- arg = -arg;
- val = atan2(arg, arg2);
- BOOST_CHECK_CLOSE_FRACTION(val, -boost::math::constants::three_quarters_pi<T>(), tol);
- arg = std::numeric_limits<T>::infinity();
- arg2 = std::numeric_limits<T>::infinity();
- val = atan2(arg, arg2);
- BOOST_CHECK_CLOSE_FRACTION(val, ldexp(boost::math::constants::pi<T>(), -2), tol);
- arg = -arg;
- val = atan2(arg, arg2);
- BOOST_CHECK_CLOSE_FRACTION(val, -ldexp(boost::math::constants::pi<T>(), -2), tol);
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- arg2 = 2;
- check_invalid(atan2(arg, arg2));
- std::swap(arg, arg2);
- check_invalid(atan2(arg, arg2));
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(atan2(arg, arg2));
- }
- }
- // F.9.1.5:
- arg = 0;
- val = cos(arg);
- BOOST_CHECK_EQUAL(val, 1);
- arg = -arg;
- BOOST_CHECK_EQUAL(val, 1);
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- check_invalid(cos(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(cos(arg));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(cos(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(cos(arg));
- }
- // F.9.1.6:
- arg = 0;
- val = sin(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = sin(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- check_invalid(sin(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(sin(arg));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(sin(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(sin(arg));
- }
- // F.9.1.7:
- arg = 0;
- val = tan(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = tan(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- check_invalid(tan(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(tan(arg));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(tan(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(tan(arg));
- }
- // F.9.2.1:
- arg = 1;
- val = acosh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- check_invalid(acosh(arg));
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = acosh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(acosh(arg));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(acosh(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(acosh(arg));
- }
- // F.9.2.2:
- arg = 0;
- val = asinh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = asinh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = asinh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -std::numeric_limits<T>::infinity();
- val = asinh(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(asinh(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(asinh(arg));
- }
- // F.9.2.3:
- arg = 0;
- val = atanh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = atanh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- arg = 2;
- check_invalid(atanh(arg));
- arg = -3;
- check_invalid(atanh(arg));
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 1;
- val = atanh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- BOOST_CHECK(signbit(val) == 0);
- check_erange(val);
- arg = -arg;
- val = atanh(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- BOOST_CHECK(signbit(val));
- check_erange(val);
- arg = std::numeric_limits<T>::infinity();
- check_invalid(atanh(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(atanh(arg));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(atanh(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(atanh(arg));
- }
- // F.9.2.4:
- arg = 0;
- val = cosh(arg);
- BOOST_CHECK_EQUAL(val, 1);
- arg = -arg;
- if (signbit(arg))
- {
- val = cosh(arg);
- BOOST_CHECK_EQUAL(val, 1);
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = (std::numeric_limits<T>::max)();
- val = cosh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = cosh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = std::numeric_limits<T>::infinity();
- val = cosh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = cosh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(cosh(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(cosh(arg));
- }
- // F.9.2.5:
- arg = 0;
- val = sinh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = sinh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = (std::numeric_limits<T>::max)();
- val = sinh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = sinh(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- arg = std::numeric_limits<T>::infinity();
- val = sinh(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = sinh(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(sinh(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(sinh(arg));
- }
- // F.9.2.6:
- arg = 0;
- val = tanh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = tanh(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- arg = (std::numeric_limits<T>::max)();
- val = tanh(arg);
- BOOST_CHECK_EQUAL(val, 1);
- arg = -arg;
- val = tanh(arg);
- BOOST_CHECK_EQUAL(val, -1);
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = tanh(arg);
- BOOST_CHECK_EQUAL(val, 1);
- arg = -arg;
- val = tanh(arg);
- BOOST_CHECK_EQUAL(val, -1);
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(tanh(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(tanh(arg));
- }
- // F.9.3.1:
- arg = 0;
- val = exp(arg);
- BOOST_CHECK_EQUAL(val, 1);
- arg = -arg;
- if (signbit(arg))
- {
- val = exp(arg);
- BOOST_CHECK_EQUAL(val, 1);
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = exp(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = exp(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = (std::numeric_limits<T>::max)();
- val = exp(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = exp(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(exp(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(exp(arg));
- }
- // F.9.3.2:
- arg = 0;
- val = exp2(arg);
- BOOST_CHECK_EQUAL(val, 1);
- arg = -arg;
- if (signbit(arg))
- {
- val = exp2(arg);
- BOOST_CHECK_EQUAL(val, 1);
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = exp2(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = exp2(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = (std::numeric_limits<T>::max)();
- val = exp2(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = exp2(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(exp2(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(exp2(arg));
- }
- // F.9.3.3:
- arg = 0;
- val = expm1(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = expm1(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = expm1(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = expm1(arg);
- BOOST_CHECK_EQUAL(val, -1);
- arg = (std::numeric_limits<T>::max)();
- val = expm1(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = expm1(arg);
- BOOST_CHECK_EQUAL(val, -1);
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(expm1(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(expm1(arg));
- }
- // F.9.3.4:
- arg = 0;
- int ival;
- val = frexp(arg, &ival);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK_EQUAL(ival, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = frexp(arg, &ival);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = frexp(arg, &ival);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = frexp(arg, &ival);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- val = frexp(arg, &ival);
- BOOST_CHECK(isnan(val));
- }
- // F.9.3.5:
- typename T::backend_type::exponent_type eval;
- typename T::backend_type::exponent_type fp_ilogb0 = (std::numeric_limits<typename T::backend_type::exponent_type>::min)();
- typename T::backend_type::exponent_type fp_ilogbnan =
- #ifdef FP_ILOGBNAN
- FP_ILOGBNAN < 0 ? (std::numeric_limits<typename T::backend_type::exponent_type>::min)() : (std::numeric_limits<typename T::backend_type::exponent_type>::max)();
- #else
- INT_MAX;
- #endif
- arg = 0;
- eval = ilogb(arg);
- BOOST_CHECK_EQUAL(eval, fp_ilogb0);
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- eval = ilogb(arg);
- BOOST_CHECK_EQUAL(eval, (std::numeric_limits<typename T::backend_type::exponent_type>::max)());
- arg = -arg;
- eval = ilogb(arg);
- BOOST_CHECK_EQUAL(eval, (std::numeric_limits<typename T::backend_type::exponent_type>::max)());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- eval = ilogb(arg);
- BOOST_CHECK_EQUAL(eval, fp_ilogbnan);
- }
- // F.9.3.7:
- arg = 1;
- val = log(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 0;
- val = log(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -arg;
- if (signbit(arg))
- {
- val = log(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- }
- arg = -1;
- check_invalid(log(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(log(arg));
- arg = std::numeric_limits<T>::infinity();
- val = log(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(log(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(log(arg));
- }
- // F.9.3.8:
- arg = 1;
- val = log10(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 0;
- val = log10(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -arg;
- if (signbit(arg))
- {
- val = log10(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- }
- arg = -1;
- check_invalid(log10(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(log10(arg));
- arg = std::numeric_limits<T>::infinity();
- val = log10(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(log10(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(log10(arg));
- }
- // F.9.3.9:
- arg = 0;
- val = log1p(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = log1p(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = -1;
- val = log1p(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -2;
- check_invalid(log1p(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(log1p(arg));
- arg = std::numeric_limits<T>::infinity();
- val = log1p(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(log1p(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(log1p(arg));
- }
- // F.9.3.10:
- arg = 1;
- val = log2(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 0;
- val = log2(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -arg;
- if (signbit(arg))
- {
- val = log2(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- }
- arg = -1;
- check_invalid(log2(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(log2(arg));
- arg = std::numeric_limits<T>::infinity();
- val = log2(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(log2(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(log2(arg));
- }
- // F.9.3.11:
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 0;
- val = logb(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -arg;
- if (signbit(arg))
- {
- val = logb(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- }
- arg = std::numeric_limits<T>::infinity();
- val = logb(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -std::numeric_limits<T>::infinity();
- val = logb(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(logb(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(logb(arg));
- }
- // F.9.3.13:
- arg = 0;
- val = scalbn(arg, 2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = scalbn(arg, 2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = scalbn(arg, -100);
- BOOST_CHECK_EQUAL(val, arg);
- arg = -arg;
- val = scalbn(arg, -100);
- BOOST_CHECK_EQUAL(val, arg);
- }
- // F.9.4.1:
- arg = 0;
- val = cbrt(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = cbrt(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- #if !(defined(TEST_FLOAT128) && defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION < 40800))
- //
- // This test fails with early implementations of libquadmath - not our issue!
- //
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = cbrt(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -std::numeric_limits<T>::infinity();
- val = cbrt(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- #endif
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(cbrt(arg));
- arg = -std::numeric_limits<T>::quiet_NaN();
- check_invalid(cbrt(arg));
- }
- // F.9.4.2:
- arg = 0;
- val = fabs(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = fabs(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = fabs(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -std::numeric_limits<T>::infinity();
- val = fabs(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- // F.9.4.3:
- arg = 2;
- arg2 = 0;
- val = hypot(arg, arg2);
- BOOST_CHECK_EQUAL(val, arg);
- arg2 = -arg2;
- val = hypot(arg, arg2);
- BOOST_CHECK_EQUAL(val, arg);
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- arg2 = 2;
- val = hypot(arg, arg2);
- BOOST_CHECK_EQUAL(val, arg);
- arg = -arg;
- val = hypot(arg, arg2);
- BOOST_CHECK_EQUAL(val, -arg);
- arg2 = std::numeric_limits<T>::quiet_NaN();
- val = hypot(arg, arg2);
- BOOST_CHECK_EQUAL(val, -arg);
- arg = -arg;
- val = hypot(arg, arg2);
- BOOST_CHECK_EQUAL(val, arg);
- }
- // F.9.4.4:
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 0;
- arg2 = -3;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -arg;
- if (signbit(arg))
- {
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- }
- arg = 0;
- arg2 = -2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -arg;
- if (signbit(arg))
- {
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- check_erange(val);
- }
- arg = 0;
- arg2 = 3;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- arg = 0;
- arg2 = 2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- }
- arg = -1;
- arg2 = std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg2 = -std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg = 1;
- arg2 = 0;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg2 = std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg2 = -std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg2 = std::numeric_limits<T>::quiet_NaN();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg = 0;
- arg2 = 0;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg2 = -arg2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg = std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg2 = -arg2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg = std::numeric_limits<T>::quiet_NaN();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- arg2 = -arg2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 1);
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = -2.5;
- arg2 = 2.5;
- check_invalid(pow(arg, arg2));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 0.5;
- arg2 = -std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -0.25;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = 2.5;
- arg2 = -std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- arg = -arg;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- arg = 2.5;
- arg2 = std::numeric_limits<T>::infinity();
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -std::numeric_limits<T>::infinity();
- arg2 = -3;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- if (signbit(-T(0)))
- BOOST_CHECK(signbit(val));
- arg2 = -2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg2 = -2.5;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg2 = 3;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- arg2 = 2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg2 = 2.5;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg; // +INF
- arg2 = -2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg2 = -3;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg2 = -3.5;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg2 = 2;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg2 = 3;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg2 = 3.5;
- val = pow(arg, arg2);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- // F.9.4.5:
- arg = 0;
- val = sqrt(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = sqrt(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- #if !(defined(TEST_FLOAT128) && defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION < 40800))
- //
- // This test fails with early implementations of libquadmath - not our issue!
- //
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = sqrt(arg);
- BOOST_CHECK_EQUAL(val, arg);
- arg = -arg;
- check_invalid(sqrt(arg));
- }
- #endif
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(sqrt(arg));
- }
- // F.9.5.1:
- arg = 0;
- val = erf(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = erf(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = erf(arg);
- BOOST_CHECK_EQUAL(val, 1);
- arg = -arg;
- val = erf(arg);
- BOOST_CHECK_EQUAL(val, -1);
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(erf(arg));
- }
- // F.9.5.2:
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = erfc(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- val = erfc(arg);
- BOOST_CHECK_EQUAL(val, 2);
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(erfc(arg));
- }
- // F.9.5.3:
- arg = 1;
- val = lgamma(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = 2;
- val = lgamma(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- #if !defined(BOOST_MPFR_VERSION) || (BOOST_MPFR_VERSION > 30103)
- arg = 0;
- val = lgamma(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -1;
- val = lgamma(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -2;
- val = lgamma(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -std::numeric_limits<T>::infinity();
- val = lgamma(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- #endif
- arg = std::numeric_limits<T>::infinity();
- val = lgamma(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(lgamma(arg));
- }
- // F.9.5.4:
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = 0;
- val = tgamma(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- check_erange(val);
- arg = -arg;
- if (signbit(arg))
- {
- val = tgamma(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- check_erange(val);
- }
- arg = -1;
- check_invalid(tgamma(arg));
- arg = -std::numeric_limits<T>::infinity();
- check_invalid(tgamma(arg));
- arg = std::numeric_limits<T>::infinity();
- val = tgamma(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(tgamma(arg));
- }
- // F.9.6.1:
- arg = 0;
- val = ceil(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = ceil(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = ceil(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = ceil(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(ceil(arg));
- }
- // F.9.6.2:
- arg = 0;
- val = floor(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = floor(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = floor(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = floor(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(floor(arg));
- }
- // F.9.6.3:
- arg = 0;
- val = nearbyint(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = nearbyint(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = nearbyint(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = nearbyint(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(nearbyint(arg));
- }
- // F.9.6.4:
- arg = 0;
- val = rint(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = rint(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = rint(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = rint(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(rint(arg));
- }
- // F.9.6.6:
- arg = 0;
- val = round(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = round(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = round(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = round(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(round(arg));
- }
- // F.9.6.8:
- arg = 0;
- val = trunc(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = trunc(arg);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- val = trunc(arg);
- BOOST_CHECK_EQUAL(val, std::numeric_limits<T>::infinity());
- arg = -arg;
- val = trunc(arg);
- BOOST_CHECK_EQUAL(val, -std::numeric_limits<T>::infinity());
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- check_invalid(trunc(arg));
- }
- // F.9.7.1:
- arg = 0;
- arg2 = 2;
- val = fmod(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val) == 0);
- arg = -arg;
- if (signbit(arg))
- {
- val = fmod(arg, arg2);
- BOOST_CHECK_EQUAL(val, 0);
- BOOST_CHECK(signbit(val));
- }
- if (std::numeric_limits<T>::has_infinity)
- {
- arg = std::numeric_limits<T>::infinity();
- check_invalid(fmod(arg, arg2));
- arg = -arg;
- check_invalid(fmod(arg, arg2));
- arg = 2;
- arg2 = 0;
- check_invalid(fmod(arg, arg2));
- check_invalid(fmod(arg, -arg2));
- }
- if (std::numeric_limits<T>::has_quiet_NaN)
- {
- arg = std::numeric_limits<T>::quiet_NaN();
- arg2 = 2;
- check_invalid(fmod(arg, arg2));
- swap(arg, arg2);
- check_invalid(fmod(arg, arg2));
- check_invalid(fmod(arg2, arg2));
- }
- //
- // Bugs:
- //
- int sign = 0;
- boost::math::lgamma(T(0.000001), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(0.5), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(0.9), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(1.1), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(1.9), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(2.1), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(20), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(-0.0000000000001), &sign);
- BOOST_CHECK_EQUAL(sign, -1);
- sign = 0;
- boost::math::lgamma(T(-0.5), &sign);
- BOOST_CHECK_EQUAL(sign, -1);
- sign = 0;
- boost::math::lgamma(T(-1.5), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- sign = 0;
- boost::math::lgamma(T(-2.5), &sign);
- BOOST_CHECK_EQUAL(sign, -1);
- sign = 0;
- boost::math::lgamma(T(-3.5), &sign);
- BOOST_CHECK_EQUAL(sign, 1);
- }
- int main()
- {
- test_poison<float>();
- test_poison<double>();
- #ifdef TEST_MPF_50
- test<boost::multiprecision::mpf_float_50>();
- test<boost::multiprecision::mpf_float_100>();
- #endif
- #ifdef TEST_MPFR_50
- std::cout << "Testing MPFR: " << MPFR_VERSION_STRING << std::endl;
- test<boost::multiprecision::mpfr_float_50>();
- test<boost::multiprecision::mpfr_float_100>();
- test_c99_appendix_F<boost::multiprecision::mpfr_float_50>();
- #endif
- #ifdef TEST_MPFI_50
- test<boost::multiprecision::mpfi_float_50>();
- test<boost::multiprecision::mpfi_float_100>();
- #endif
- #ifdef TEST_CPP_DEC_FLOAT
- test<boost::multiprecision::cpp_dec_float_50>();
- #if !(defined(__GNUC__) && defined(_WIN32)) // Object file too large otherwise
- test<boost::multiprecision::cpp_dec_float_100>();
- #endif
- test_c99_appendix_F<boost::multiprecision::cpp_dec_float_50>();
- #endif
- #ifdef TEST_CPP_DEC_FLOAT_2
- // Some "peculiar" digit counts which stress our code:
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<65> > >();
- #if !(defined(__GNUC__) && defined(_WIN32)) // Object file too large otherwise
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<64> > >();
- #endif
- #endif
- #ifdef TEST_CPP_DEC_FLOAT_3
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<63> > >();
- #if !(defined(__GNUC__) && defined(_WIN32)) // Object file too large otherwise
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<62> > >();
- #endif
- #endif
- #ifdef TEST_CPP_DEC_FLOAT_4
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<61, long long> > >();
- #if !(defined(__GNUC__) && defined(_WIN32)) // Object file too large otherwise
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<60, long long> > >();
- #endif
- #endif
- #ifdef TEST_CPP_DEC_FLOAT_5
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<59, long long, std::allocator<char> > > >();
- #endif
- #ifdef TEST_CPP_DEC_FLOAT_6
- test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<58, long long, std::allocator<char> > > >();
- #endif
- #ifdef TEST_CPP_BIN_FLOAT
- test<boost::multiprecision::cpp_bin_float_50>();
- test<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<100>, boost::multiprecision::et_on> >();
- #endif
- #ifdef TEST_CPP_BIN_FLOAT_2
- test<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<35, boost::multiprecision::digit_base_10, std::allocator<char>, boost::long_long_type> > >();
- #endif
- #ifdef TEST_CPP_BIN_FLOAT_3
- test_c99_appendix_F<boost::multiprecision::cpp_bin_float_50>();
- test_c99_appendix_F<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<100>, boost::multiprecision::et_on> >();
- #endif
- #ifdef TEST_FLOAT128
- test<boost::multiprecision::float128>();
- test_c99_appendix_F<boost::multiprecision::float128>();
- #endif
- return boost::report_errors();
- }
|