python test set math module xxxx should not do tests around zero only detect evidence of doublerounding fsum is not always correctly rounded on machines that suffer from double rounding locate file with test values convert a nonnan float x to an integer in such a way that adjacent floats are converted to adjacent integers then absulpsx ulpsy gives the difference in ulps between two floats the results from this function will only make sense on platforms where native doubles are represented in ieee 754 binary64 format note 0 0 and 0 0 are converted to 0 and 1 respectively here s a pure python version of the math factorial algorithm for documentation and comparison purposes formula factorialn factorialoddpartn n countsetbitsn where factorialoddpartn producti 0 product0 j n i j odd j the outer product above is an infinite product but once i n bitlength n i 1 and the corresponding term of the product is empty so only the finitely many terms for 0 i n bitlength contribute anything we iterate downwards from i n bitlength 1 to i 0 the inner product in the formula above starts at 1 for i n bitlength for each i n bitlength we get the inner product for i from that for i 1 by multiplying by all j in n i1 j n i j odd in python terms this set is rangen i1 1 1 n i 1 1 2 number of 1 bits in binary expansion of a nonnnegative integer return 1 countsetbitsn n 1 if n else 0 def partialproductstart stop numfactors stop start 1 if not numfactors return 1 elif numfactors 1 return start else mid start numfactors 1 return partialproductstart mid partialproductmid stop def pyfactorialn inner outer 1 for i in reversedrangen bitlength inner partialproductn i 1 1 1 n i 1 1 outer inner return outer n countsetbitsn def ulpabscheckexpected got ulptol abstol ulperror abstoulpsexpected toulpsgot abserror absexpected got succeed if either abserror abstol or ulperror ulptol if abserror abstol or ulperror ulptol return none else fmt error 3g d ulps permitted error 3g or d ulps return fmt formatabserror ulperror abstol ulptol def parsemtestfilefname with openfname encodingutf8 as fp for line in fp strip comments and skip blank lines if in line line line line index if not line strip continue lhs rhs line split id fn arg lhs split rhspieces rhs split exp rhspieces0 flags rhspieces1 yield id fn floatarg floatexp flags def parsetestfilefname with openfname encodingutf8 as fp for line in fp skip comment lines and blank lines if line startswith or not line strip continue lhs rhs line split id fn argreal argimag lhs split rhspieces rhs split expreal expimag rhspieces0 rhspieces1 flags rhspieces2 yield id fn floatargreal floatargimag floatexpreal floatexpimag flags def resultcheckexpected got ulptol5 abstol0 0 common logic of mathtests ftest testtestcases testmtestcases check exactly equal applies also to strings representing exceptions if got expected return none failure not equal turn mixed float and int comparison e g floor to allfloat if isinstanceexpected float and isinstancegot int got floatgot elif isinstancegot float and isinstanceexpected int expected floatexpected if isinstanceexpected float and isinstancegot float if math isnanexpected and math isnangot pass since both nan failure none elif math isinfexpected or math isinfgot we already know they re not equal drop through to failure pass else both are finite floats now are they close enough failure ulpabscheckexpected got ulptol abstol arguments are not equal and if numeric are too far apart if failure is not none failfmt expected r got r failmsg failfmt formatexpected got failmsg formatfailure return failmsg else return none class floatlike def initself value self value value def floatself return self value class intsubclassint pass class providing an index method class myindexableobject def initself value self value value def indexself return self value class baddescr def getself obj objtypenone raise valueerror class mathtestsunittest testcase def ftestself name got expected ulptol5 abstol0 0 failure resultcheckexpected got ulptol abstol if failure is not none self fail formatname failure def testconstantsself ref abramowitz stegun dover 1965 self ftest pi math pi 3 141592653589793238462643 self ftest e math e 2 718281828459045235360287 self assertequalmath tau 2math pi def testacosself self assertraisestypeerror math acos self ftest acos1 math acos1 math pi self ftest acos0 math acos0 math pi2 self ftest acos1 math acos1 0 self assertraisesvalueerror math acos inf self assertraisesvalueerror math acos ninf self assertraisesvalueerror math acos 1 eps self assertraisesvalueerror math acos 1 eps self asserttruemath isnanmath acosnan def testacoshself self assertraisestypeerror math acosh self ftest acosh1 math acosh1 0 self ftest acosh2 math acosh2 1 3169578969248168 self assertraisesvalueerror math acosh 0 self assertraisesvalueerror math acosh 1 self assertequalmath acoshinf inf self assertraisesvalueerror math acosh ninf self asserttruemath isnanmath acoshnan def testasinself self assertraisestypeerror math asin self ftest asin1 math asin1 math pi2 self ftest asin0 math asin0 0 self ftest asin1 math asin1 math pi2 self assertraisesvalueerror math asin inf self assertraisesvalueerror math asin ninf self assertraisesvalueerror math asin 1 eps self assertraisesvalueerror math asin 1 eps self asserttruemath isnanmath asinnan def testasinhself self assertraisestypeerror math asinh self ftest asinh0 math asinh0 0 self ftest asinh1 math asinh1 0 88137358701954305 self ftest asinh1 math asinh1 0 88137358701954305 self assertequalmath asinhinf inf self assertequalmath asinhninf ninf self asserttruemath isnanmath asinhnan def testatanself self assertraisestypeerror math atan self ftest atan1 math atan1 math pi4 self ftest atan0 math atan0 0 self ftest atan1 math atan1 math pi4 self ftest ataninf math ataninf math pi2 self ftest ataninf math atanninf math pi2 self asserttruemath isnanmath atannan def testatanhself self assertraisestypeerror math atan self ftest atanh0 math atanh0 0 self ftest atanh0 5 math atanh0 5 0 54930614433405489 self ftest atanh0 5 math atanh0 5 0 54930614433405489 self assertraisesvalueerror math atanh 1 self assertraisesvalueerror math atanh 1 self assertraisesvalueerror math atanh inf self assertraisesvalueerror math atanh ninf self asserttruemath isnanmath atanhnan def testatan2self self assertraisestypeerror math atan2 self ftest atan21 0 math atan21 0 math pi2 self ftest atan21 1 math atan21 1 math pi4 self ftest atan20 1 math atan20 1 0 self ftest atan21 1 math atan21 1 math pi4 self ftest atan21 0 math atan21 0 math pi2 self ftest atan21 1 math atan21 1 3math pi4 math atan20 x self ftest atan20 inf math atan20 ninf math pi self ftest atan20 2 3 math atan20 2 3 math pi self ftest atan20 0 math atan20 0 math pi self assertequalmath atan20 0 0 self assertequalmath atan20 2 3 0 self assertequalmath atan20 inf 0 self asserttruemath isnanmath atan20 nan math atan20 x self ftest atan20 inf math atan20 ninf math pi self ftest atan20 2 3 math atan20 2 3 math pi self ftest atan20 0 math atan20 0 math pi self assertequalmath atan20 0 0 self assertequalmath atan20 2 3 0 self assertequalmath atan20 inf 0 self asserttruemath isnanmath atan20 nan math atan2inf x self ftest atan2inf inf math atan2inf ninf math pi34 self ftest atan2inf 2 3 math atan2inf 2 3 math pi2 self ftest atan2inf 0 math atan2inf 0 0 math pi2 self ftest atan2inf 0 math atan2inf 0 0 math pi2 self ftest atan2inf 2 3 math atan2inf 2 3 math pi2 self ftest atan2inf inf math atan2inf inf math pi4 self asserttruemath isnanmath atan2inf nan math atan2ninf x self ftest atan2inf inf math atan2ninf ninf math pi34 self ftest atan2inf 2 3 math atan2ninf 2 3 math pi2 self ftest atan2inf 0 math atan2ninf 0 0 math pi2 self ftest atan2inf 0 math atan2ninf 0 0 math pi2 self ftest atan2inf 2 3 math atan2ninf 2 3 math pi2 self ftest atan2inf inf math atan2ninf inf math pi4 self asserttruemath isnanmath atan2ninf nan math atan2finite x self ftest atan22 3 inf math atan22 3 ninf math pi self ftest atan22 3 0 math atan22 3 0 math pi2 self ftest atan22 3 0 math atan22 3 0 math pi2 self assertequalmath atan22 3 inf 0 self asserttruemath isnanmath atan22 3 nan math atan2finite x self ftest atan22 3 inf math atan22 3 ninf math pi self ftest atan22 3 0 math atan22 3 0 math pi2 self ftest atan22 3 0 math atan22 3 0 math pi2 self assertequalmath atan22 3 inf 0 self asserttruemath isnanmath atan22 3 nan math atan2nan x self asserttruemath isnanmath atan2nan ninf self asserttruemath isnanmath atan2nan 2 3 self asserttruemath isnanmath atan2nan 0 self asserttruemath isnanmath atan2nan 0 self asserttruemath isnanmath atan2nan 2 3 self asserttruemath isnanmath atan2nan inf self asserttruemath isnanmath atan2nan nan def testcbrtself self assertraisestypeerror math cbrt self ftest cbrt0 math cbrt0 0 self ftest cbrt1 math cbrt1 1 self ftest cbrt8 math cbrt8 2 self ftest cbrt0 0 math cbrt0 0 0 0 self ftest cbrt0 0 math cbrt0 0 0 0 self ftest cbrt1 2 math cbrt1 2 1 062658569182611 self ftest cbrt2 6 math cbrt2 6 1 375068867074141 self ftest cbrt27 math cbrt27 3 self ftest cbrt1 math cbrt1 1 self ftest cbrt27 math cbrt27 3 self assertequalmath cbrtinf inf self assertequalmath cbrtninf ninf self asserttruemath isnanmath cbrtnan def testceilself self assertraisestypeerror math ceil self assertequalint typemath ceil0 5 self assertequalmath ceil0 5 1 self assertequalmath ceil1 0 1 self assertequalmath ceil1 5 2 self assertequalmath ceil0 5 0 self assertequalmath ceil1 0 1 self assertequalmath ceil1 5 1 self assertequalmath ceil0 0 0 self assertequalmath ceil0 0 0 self assertequalmath ceilinf inf self assertequalmath ceilninf ninf self asserttruemath isnanmath ceilnan class testceil def ceilself return 42 class floatceilfloat def ceilself return 42 class testnoceil pass class testbadceil ceil baddescr self assertequalmath ceiltestceil 42 self assertequalmath ceilfloatceil 42 self assertequalmath ceilfloatlike42 5 43 self assertraisestypeerror math ceil testnoceil self assertraisesvalueerror math ceil testbadceil t testnoceil t ceil lambda args args self assertraisestypeerror math ceil t self assertraisestypeerror math ceil t 0 self assertequalmath ceilfloatlike1 0 1 0 self assertequalmath ceilfloatlike1 0 1 0 requiresieee754 def testcopysignself self assertequalmath copysign1 42 1 0 self assertequalmath copysign0 42 0 0 self assertequalmath copysign1 42 1 0 self assertequalmath copysign3 0 3 0 self assertequalmath copysign4 0 4 0 self assertraisestypeerror math copysign copysign should let us distinguish signs of zeros self assertequalmath copysign1 0 1 self assertequalmath copysign1 0 1 self assertequalmath copysigninf 0 inf self assertequalmath copysigninf 0 ninf self assertequalmath copysignninf 0 inf self assertequalmath copysignninf 0 ninf and of infinities self assertequalmath copysign1 inf 1 self assertequalmath copysign1 ninf 1 self assertequalmath copysigninf inf inf self assertequalmath copysigninf ninf ninf self assertequalmath copysignninf inf inf self assertequalmath copysignninf ninf ninf self asserttruemath isnanmath copysignnan 1 self asserttruemath isnanmath copysignnan inf self asserttruemath isnanmath copysignnan ninf self asserttruemath isnanmath copysignnan nan copysigninf nan may be inf or it may be ninf since we don t know whether the sign bit of nan is set on any given platform self asserttruemath isinfmath copysigninf nan similarly copysign2 nan could be 2 or 2 self assertequalabsmath copysign2 nan 2 def testcosself self assertraisestypeerror math cos self ftest cospi2 math cosmath pi2 0 abstolmath ulp1 self ftest cos0 math cos0 1 self ftest cospi2 math cosmath pi2 0 abstolmath ulp1 self ftest cospi math cosmath pi 1 try self asserttruemath isnanmath cosinf self asserttruemath isnanmath cosninf except valueerror self assertraisesvalueerror math cos inf self assertraisesvalueerror math cos ninf self asserttruemath isnanmath cosnan unittest skipifsys platform win32 and platform machine in arm arm64 windows ucrt is off by 2 ulp this test requires accuracy within 1 ulp def testcoshself self assertraisestypeerror math cosh self ftest cosh0 math cosh0 1 self ftest cosh22cosh12 math cosh22math cosh12 1 thanks to lambert self assertequalmath coshinf inf self assertequalmath coshninf inf self asserttruemath isnanmath coshnan def testdegreesself self assertraisestypeerror math degrees self ftest degreespi math degreesmath pi 180 0 self ftest degreespi2 math degreesmath pi2 90 0 self ftest degreespi4 math degreesmath pi4 45 0 self ftest degrees0 math degrees0 0 def testexpself self assertraisestypeerror math exp self ftest exp1 math exp1 1math e self ftest exp0 math exp0 1 self ftest exp1 math exp1 math e self assertequalmath expinf inf self assertequalmath expninf 0 self asserttruemath isnanmath expnan self assertraisesoverflowerror math exp 1000000 def testexp2self self assertraisestypeerror math exp2 self ftest exp21 math exp21 0 5 self ftest exp20 math exp20 1 self ftest exp21 math exp21 2 self ftest exp22 3 math exp22 3 4 924577653379665 self assertequalmath exp2inf inf self assertequalmath exp2ninf 0 self asserttruemath isnanmath exp2nan self assertraisesoverflowerror math exp2 1000000 def testfabsself self assertraisestypeerror math fabs self ftest fabs1 math fabs1 1 self ftest fabs0 math fabs0 0 self ftest fabs1 math fabs1 1 def testfactorialself self assertequalmath factorial0 1 total 1 for i in range1 1000 total i self assertequalmath factoriali total self assertequalmath factoriali pyfactoriali self assertraisesvalueerror math factorial 1 self assertraisesvalueerror math factorial 10100 def testfactorialnonintegersself self assertraisestypeerror math factorial 5 0 self assertraisestypeerror math factorial 5 2 self assertraisestypeerror math factorial 1 0 self assertraisestypeerror math factorial 1e100 self assertraisestypeerror math factorial decimal decimal 5 self assertraisestypeerror math factorial decimal decimal 5 2 self assertraisestypeerror math factorial 5 other implementations may place different upper bounds support cpythononly def testfactorialhugeinputsself currently raises overflowerror for inputs that are too large to fit into a c long self assertraisesoverflowerror math factorial 10100 self assertraisestypeerror math factorial 1e100 def testfloorself self assertraisestypeerror math floor self assertequalint typemath floor0 5 self assertequalmath floor0 5 0 self assertequalmath floor1 0 1 self assertequalmath floor1 5 1 self assertequalmath floor0 5 1 self assertequalmath floor1 0 1 self assertequalmath floor1 5 2 self assertequalmath ceilinf inf self assertequalmath ceilninf ninf self asserttruemath isnanmath floornan class testfloor def floorself return 42 class floatfloorfloat def floorself return 42 class testnofloor pass class testbadfloor floor baddescr self assertequalmath floortestfloor 42 self assertequalmath floorfloatfloor 42 self assertequalmath floorfloatlike41 9 41 self assertraisestypeerror math floor testnofloor self assertraisesvalueerror math floor testbadfloor t testnofloor t floor lambda args args self assertraisestypeerror math floor t self assertraisestypeerror math floor t 0 self assertequalmath floorfloatlike1 0 1 0 self assertequalmath floorfloatlike1 0 1 0 def testfmodself self assertraisestypeerror math fmod self ftest fmod10 1 math fmod10 1 0 0 self ftest fmod10 0 5 math fmod10 0 5 0 0 self ftest fmod10 1 5 math fmod10 1 5 1 0 self ftest fmod10 1 math fmod10 1 0 0 self ftest fmod10 0 5 math fmod10 0 5 0 0 self ftest fmod10 1 5 math fmod10 1 5 1 0 self asserttruemath isnanmath fmodnan 1 self asserttruemath isnanmath fmod1 nan self asserttruemath isnanmath fmodnan nan self assertraisesvalueerror math fmod 1 0 self assertraisesvalueerror math fmod inf 1 self assertraisesvalueerror math fmod ninf 1 self assertraisesvalueerror math fmod inf 0 self assertequalmath fmod3 0 inf 3 0 self assertequalmath fmod3 0 inf 3 0 self assertequalmath fmod3 0 ninf 3 0 self assertequalmath fmod3 0 ninf 3 0 self assertequalmath fmod0 0 3 0 0 0 self assertequalmath fmod0 0 ninf 0 0 self assertraisesvalueerror math fmod inf inf def testfrexpself self assertraisestypeerror math frexp def testfrexpname result expected mant exp emant eexp result expected if absmantemant eps or exp eexp self fail s returned r expected r name result expected testfrexp frexp1 math frexp1 0 5 1 testfrexp frexp0 math frexp0 0 0 testfrexp frexp1 math frexp1 0 5 1 testfrexp frexp2 math frexp2 0 5 2 self assertequalmath frexpinf0 inf self assertequalmath frexpninf0 ninf self asserttruemath isnanmath frexpnan0 requiresieee754 unittest skipifhavedoublerounding fsum is not exact on machines with double rounding def testfsumself math fsum relies on exact rounding for correct operation there s a known problem with ia32 floatingpoint that causes inexact rounding in some situations and will cause the math fsum tests below to fail see issue 2937 on non ieee 754 platforms and on ieee 754 platforms that exhibit the problem described in issue 2937 we simply skip the whole test python version of math fsum for comparison uses a different algorithm based on frexp ldexp and integer arithmetic from sys import floatinfo mantdig floatinfo mantdig etiny floatinfo minexp mantdig def msumiterable tmant texp 0 0 for x in iterable mant exp math frexpx mant exp intmath ldexpmant mantdig exp mantdig if texp exp tmant texpexp texp exp else mant exptexp tmant mant round tmant 2texp to a float the original recipe used floatstrtmant 2 0texp for this but that s a little unsafe because str float conversion can t be relied upon to do correct rounding on all platforms tail maxlenbinabstmant2 mantdig etiny texp if tail 0 h 1 tail1 tmant tmant 2h booltmant h and tmant 3h1 texp tail return math ldexptmant texp testvalues 0 0 0 0 0 0 1e100 1 0 1e100 1e100 1e50 1 0 1e50 1e100 1e100 1 0 1e100 1e100 1e50 1 1e50 1e100 2 053 0 5 2 054 2 0531 0 2 053 1 0 2 0100 2 0532 0 2 05310 0 1 0 2 0100 2 05312 0 2 0534 0 0 5 2 054 2 0533 0 1 n for n in range1 1001 float fromhex 0x1 df11f45f4e61ap2 1 nn for n in range1 1001 float fromhex 0x1 62a2af1bd3624p1 1e16 1 1e16 10000000000000002 0 1e162 1 2 53 1e162 1 2 53 0 0 exercise code for resizing partials array 2 n 2 n50 2 n52 for n in range1074 972 2 2 1022 float fromhex 0x1 5555555555555p970 telescoping sum with exact differences due to sterbenz terms 1 7i for i in range1001 testvalues append termsi1 termsi for i in range1000 terms1000 terms0 for i vals expected in enumeratetestvalues try actual math fsumvals except overflowerror self failtest d failed got overflowerror expected r for math fsum 100r i expected vals except valueerror self failtest d failed got valueerror expected r for math fsum 100r i expected vals self assertequalactual expected from random import random gauss shuffle for j in range1000 vals 7 1e100 7 1e100 9e20 8e20 10 s 0 for i in range200 v gauss0 random 7 s s v vals appendv shufflevals s msumvals self assertequalmsumvals math fsumvals self assertequalmath fsum1 0 math inf math inf self asserttruemath isnanmath fsummath nan 1 0 self assertequalmath fsum1e100 floatlike1 0 1e100 1e100 1e50 floatlike1 0 1e50 1e100 self assertraisesoverflowerror math fsum 1e308 1e308 self assertraisesvalueerror math fsum math inf math inf self assertraisestypeerror math fsum spam self assertraisestypeerror math fsum 1 self assertraisesoverflowerror math fsum 101000 def baditer yield 1 0 raise zerodivisionerror self assertraiseszerodivisionerror math fsum baditer def testgcdself gcd math gcd self assertequalgcd0 0 0 self assertequalgcd1 0 1 self assertequalgcd1 0 1 self assertequalgcd0 1 1 self assertequalgcd0 1 1 self assertequalgcd7 1 1 self assertequalgcd7 1 1 self assertequalgcd23 15 1 self assertequalgcd120 84 12 self assertequalgcd84 120 12 self assertequalgcd1216342683557601535506311712 436522681849110124616458784 32 x 434610456570399902378880679233098819019853229470286994367836600566 y 1064502245825115327754847244914921553977 for c in 652560 576559230871654959816130551884856912003141446781646602790216406874 a x c b y c self assertequalgcda b c self assertequalgcdb a c self assertequalgcda b c self assertequalgcdb a c self assertequalgcda b c self assertequalgcdb a c self assertequalgcda b c self assertequalgcdb a c self assertequalgcd 0 self assertequalgcd120 120 self assertequalgcd120 120 self assertequalgcd120 84 102 6 self assertequalgcd120 1 84 1 self assertraisestypeerror gcd 120 0 self assertraisestypeerror gcd 120 0 84 self assertraisestypeerror gcd 120 84 0 self assertraisestypeerror gcd 120 1 84 0 self assertequalgcdmyindexable120 myindexable84 12 def testhypotself from decimal import decimal from fractions import fraction hypot math hypot test different numbers of arguments from zero to five against a straightforward pure python implementation args math e math pi math sqrt2 0 math gamma3 5 math sin2 1 for i in rangelenargs1 self assertalmostequal hypotargs i math sqrtsums2 for s in args i test allowable types those with float self assertequalhypot12 0 5 0 13 0 self assertequalhypot12 5 13 self assertequalhypot1 1 math sqrt2 self assertequalhypot1 floatlike1 math sqrt2 self assertequalhypotdecimal12 decimal5 13 self assertequalhypotfraction12 32 fraction5 32 fraction13 32 self assertequalhypotbool1 bool0 bool1 bool1 math sqrt3 test corner cases self assertequalhypot0 0 0 0 0 0 max input is zero self assertequalhypot10 5 10 5 negative input self assertequalhypot 0 0 negative input self assertequal1 0 math copysign1 0 hypot0 0 convert negative zero to positive zero self assertequal handling of moving max to the end hypot1 5 1 5 0 5 hypot1 5 0 5 1 5 test handling of bad arguments with self assertraisestypeerror reject keyword args hypotx1 with self assertraisestypeerror reject values without float hypot1 1 string 2 2 inttoobigforfloat 10 sys floatinfo max10exp 5 with self assertraisesvalueerror overflowerror hypot1 inttoobigforfloat any infinity gives positive infinity self assertequalhypotinf inf self assertequalhypot0 inf inf self assertequalhypot10 inf inf self assertequalhypot10 inf inf self assertequalhypotnan inf inf self assertequalhypotinf nan inf self assertequalhypotninf nan inf self assertequalhypotnan ninf inf self assertequalhypotinf inf inf self assertequalhypotinf inf inf self assertequalhypot10 inf inf if no infinity any nan gives a nan self asserttruemath isnanhypotnan self asserttruemath isnanhypot0 nan self asserttruemath isnanhypotnan 10 self asserttruemath isnanhypot10 nan self asserttruemath isnanhypotnan nan self asserttruemath isnanhypotnan verify scaling for extremely large values fourthmax floatmax 4 0 for n in range32 self asserttruemath isclosehypotfourthmaxn fourthmax math sqrtn verify scaling for extremely small values for exp in range32 scale floatmin 2 0 exp self assertequalmath hypot4scale 3scale 5scale self assertraisestypeerror math hypot 1 018 spam requiresieee754 unittest skipifhavedoublerounding hypot loses accuracy on machines with double rounding def testhypotaccuracyself verify improved accuracy in cases that were known to be inaccurate the new algorithm s accuracy depends on ieee 754 arithmetic guarantees on having the usual round half even rounding mode on the system not having double rounding due to extended precision and on the compiler maintaining the specified order of operations this test is known to succeed on most of our builds if it fails some build we either need to add another skipif if the cause is identifiable otherwise we can remove this test entirely hypot math hypot decimal decimal decimal highprecision decimal contextprec500 for hx hy in cases with a 1 ulp error in python 3 7 compiled with clang 0x1 10e89518dca48p29 0x1 1970f7565b7efp30 0x1 10106eb4b44a2p29 0x1 ef0596cdc97f8p29 0x1 459c058e20bb7p30 0x1 993ca009b9178p29 0x1 378371ae67c0cp30 0x1 fbe6619854b4cp29 0x1 f4cd0574fb97ap29 0x1 50fe31669340ep30 0x1 494b2cdd3d446p29 0x1 212a5367b4c7cp29 0x1 f84e649f1e46dp29 0x1 1fa56bef8eec4p30 0x1 2e817edd3d6fap30 0x1 eb0814f1e9602p29 0x1 0d3a6e3d04245p29 0x1 32a62fea52352p30 0x1 888e19611bfc5p29 0x1 52b8e70b24353p29 cases with 2 ulp error in python 3 8 0x1 538816d48a13fp29 0x1 7967c5ca43e16p29 0x1 57b47b7234530p29 0x1 74e2c7040e772p29 0x1 821b685e9b168p30 0x1 677dc1c1e3dc6p29 0x1 9e8247f67097bp29 0x1 24bd2dc4f4baep29 0x1 b73b59e0cb5f9p29 0x1 da899ab784a97p28 0x1 94a8d2842a7cfp30 0x1 326a51d4d8d8ap30 0x1 e930b9cd99035p29 0x1 5a1030e18dff9p30 0x1 1592bbb0e4690p29 0x1 a9c337b33fb9ap29 0x1 1243a50751fd4p29 0x1 a5a10175622d9p29 0x1 57a8596e74722p30 0x1 42d1af9d04da9p30 cases with 1 ulp error in version fff3c28052e6b0 0x1 ee7dbd9565899p29 0x1 7ab4d6fc6e4b4p29 0x1 5c6bfbec5c4dcp30 0x1 02511184b4970p30 0x1 59dcebba995cap30 0x1 50ca7e7c38854p29 0x1 768cdd94cf5aap29 0x1 9cfdc5571d38ep29 0x1 dcf137d60262ep29 0x1 1101621990b3ep30 0x1 3a2d006e288b0p30 0x1 e9a240914326cp29 0x1 62a32f7f53c61p29 0x1 47eb6cd72684fp29 0x1 d3bcb60748ef2p29 0x1 3f13c4056312cp30 0x1 282bdb82f17f3p30 0x1 640ba4c4eed3ap30 0x1 89d8c423ea0c6p29 0x1 d35dcfe902bc3p29 x float fromhexhx y float fromhexhy with self subtesthxhx hyhy xx yy with decimal localcontexthighprecision z floatdecimalx2 decimaly2 sqrt self assertequalhypotx y z def testdistself from decimal import decimal as d from fractions import fraction as f dist math dist sqrt math sqrt simple exact cases self assertequaldist1 0 2 0 3 0 4 0 2 0 1 0 5 0 self assertequaldist1 2 3 4 2 1 5 0 test different numbers of arguments from zero to nine against a straightforward pure python implementation for i in range9 for j in range5 p tuplerandom uniform5 5 for k in rangei q tuplerandom uniform5 5 for k in rangei self assertalmostequal distp q sqrtsumpx qx 2 0 for px qx in zipp q test nontuple inputs self assertequaldist1 0 2 0 3 0 4 0 2 0 1 0 5 0 self assertequaldistiter1 0 2 0 3 0 iter4 0 2 0 1 0 5 0 test allowable types those with float self assertequaldist14 0 1 0 2 0 4 0 13 0 self assertequaldist14 1 2 4 13 self assertequaldistfloatlike14 1 2 4 13 self assertequaldist11 1 floatlike1 4 13 self assertequaldist14 floatlike1 2 6 13 self assertequaldist14 1 2 6 13 self assertequaldistd14 d1 d2 d4 d13 self assertequaldistf14 32 f1 32 f2 32 f4 32 f13 32 self assertequaldisttrue true false true false true false true true false sqrt2 0 test corner cases self assertequaldist13 25 12 5 3 25 13 25 12 5 3 25 0 0 distance with self is zero self assertequaldist 0 0 zerodimensional case self assertequal1 0 convert negative zero to positive zero math copysign1 0 dist0 0 0 0 self assertequal1 0 convert negative zero to positive zero math copysign1 0 dist0 0 0 0 self assertequal handling of moving max to the end dist1 5 1 5 0 5 0 0 0 dist1 5 0 5 1 5 0 0 0 verify tuple subclasses are allowed class ttuple pass self assertequaldistt1 2 3 4 2 1 5 0 test handling of bad arguments with self assertraisestypeerror reject keyword args distp1 2 3 q4 5 6 with self assertraisestypeerror too few args dist1 2 3 with self assertraisestypeerror too many args dist1 2 3 4 5 6 7 8 9 with self assertraisestypeerror scalars not allowed dist1 2 with self assertraisestypeerror reject values without float dist1 1 string 2 2 1 2 3 with self assertraisesvalueerror check dimension agree dist1 2 3 4 5 6 7 with self assertraisesvalueerror check dimension agree dist1 2 3 4 5 6 7 with self assertraisestypeerror dist1 17 spam 1 18 with self assertraisestypeerror rejects invalid types distabc xyz inttoobigforfloat 10 sys floatinfo max10exp 5 with self assertraisesvalueerror overflowerror dist1 inttoobigforfloat 2 3 with self assertraisesvalueerror overflowerror dist2 3 1 inttoobigforfloat with self assertraisestypeerror dist1 2 with self assertraisestypeerror dist1 2 class badfloat float baddescr with self assertraisesvalueerror dist1 badfloat verify that the one dimensional case is equivalent to abs for i in range20 p q random random random random self assertequaldistp q absp q test special values values ninf 10 5 0 0 0 0 10 5 inf nan for p in itertools productvalues repeat3 for q in itertools productvalues repeat3 diffs px qx for px qx in zipp q if anymapmath isinf diffs any infinite difference gives positive infinity self assertequaldistp q inf elif anymapmath isnan diffs if no infinity any nan gives a nan self asserttruemath isnandistp q verify scaling for extremely large values fourthmax floatmax 4 0 for n in range32 p fourthmax n q 0 0 n self asserttruemath isclosedistp q fourthmax math sqrtn self asserttruemath isclosedistq p fourthmax math sqrtn verify scaling for extremely small values for exp in range32 scale floatmin 2 0 exp p 4scale 3scale q 0 0 0 0 self assertequalmath distp q 5scale self assertequalmath distq p 5scale def testmathdistleakself gh98897 check for error handling does not leak memory with self assertraisesvalueerror math dist1 2 3 4 5 def testisqrtself test a variety of inputs large and small testvalues listrange1000 listrange106 1000 106 1000 2e i for e in range60 200 for i in range40 40 39999 105001 for value in testvalues with self subtestvaluevalue s math isqrtvalue self assertistypes int self assertlessequalss value self assertlessvalue s1s1 negative values with self assertraisesvalueerror math isqrt1 integerlike things s math isqrttrue self assertistypes int self assertequals 1 s math isqrtfalse self assertistypes int self assertequals 0 class integerlikeobject def initself value self value value def indexself return self value s math isqrtintegerlike1729 self assertistypes int self assertequals 41 with self assertraisesvalueerror math isqrtintegerlike3 nonintegerlike things badvalues 3 5 a string decimal decimal3 5 3 5j 100 0 4 0 for value in badvalues with self subtestvaluevalue with self assertraisestypeerror math isqrtvalue def testlcmself lcm math lcm self assertequallcm0 0 0 self assertequallcm1 0 0 self assertequallcm1 0 0 self assertequallcm0 1 0 self assertequallcm0 1 0 self assertequallcm7 1 7 self assertequallcm7 1 7 self assertequallcm23 15 345 self assertequallcm120 84 840 self assertequallcm84 120 840 self assertequallcm1216342683557601535506311712 436522681849110124616458784 16592536571065866494401400422922201534178938447014944 x 43461045657039990237 y 10645022458251153277 for c in 652560 57655923087165495981 a x c b y c d x y c self assertequallcma b d self assertequallcmb a d self assertequallcma b d self assertequallcmb a d self assertequallcma b d self assertequallcmb a d self assertequallcma b d self assertequallcmb a d self assertequallcm 1 self assertequallcm120 120 self assertequallcm120 120 self assertequallcm120 84 102 14280 self assertequallcm120 0 84 0 self assertraisestypeerror lcm 120 0 self assertraisestypeerror lcm 120 0 84 self assertraisestypeerror lcm 120 84 0 self assertraisestypeerror lcm 120 0 84 0 self assertequallcmmyindexable120 myindexable84 840 def testldexpself self assertraisestypeerror math ldexp self assertraisestypeerror math ldexp 2 0 1 1 self ftest ldexp0 1 math ldexp0 1 0 self ftest ldexp1 1 math ldexp1 1 2 self ftest ldexp1 1 math ldexp1 1 0 5 self ftest ldexp1 1 math ldexp1 1 2 self assertraisesoverflowerror math ldexp 1 1000000 self assertraisesoverflowerror math ldexp 1 1000000 self assertequalmath ldexp1 1000000 0 self assertequalmath ldexp1 1000000 0 self assertequalmath ldexpinf 30 inf self assertequalmath ldexpninf 213 ninf self asserttruemath isnanmath ldexpnan 0 large second argument for n in 105 1010 1020 1040 self assertequalmath ldexpinf n inf self assertequalmath ldexpninf n ninf self assertequalmath ldexp1 n 0 self assertequalmath ldexp1 n 0 self assertequalmath ldexp0 n 0 self assertequalmath ldexp0 n 0 self asserttruemath isnanmath ldexpnan n self assertraisesoverflowerror math ldexp 1 n self assertraisesoverflowerror math ldexp 1 n self assertequalmath ldexp0 n 0 self assertequalmath ldexp0 n 0 self assertequalmath ldexpinf n inf self assertequalmath ldexpninf n ninf self asserttruemath isnanmath ldexpnan n def testlogself self assertraisestypeerror math log self assertraisestypeerror math log 1 2 3 self ftest log1e math log1math e 1 self ftest log1 math log1 0 self ftest loge math logmath e 1 self ftest log32 2 math log32 2 5 self ftest log1040 10 math log1040 10 40 self ftest log1040 1020 math log1040 1020 2 self ftest log101000 math log101000 2302 5850929940457 self assertraisesvalueerror math log 1 5 self assertraisesvalueerror math log 101000 self assertraisesvalueerror math log 10 10 self assertraisesvalueerror math log ninf self assertequalmath loginf inf self asserttruemath isnanmath lognan def testlog1pself self assertraisestypeerror math log1p for n in 2 290 2300 self assertalmostequalmath log1pn math log1pfloatn self assertraisesvalueerror math log1p 1 self assertequalmath log1pinf inf requiresieee754 def testlog2self self assertraisestypeerror math log2 check some integer values self assertequalmath log21 0 0 self assertequalmath log22 1 0 self assertequalmath log24 2 0 large integer values self assertequalmath log221023 1023 0 self assertequalmath log221024 1024 0 self assertequalmath log222000 2000 0 self assertraisesvalueerror math log2 1 5 self assertraisesvalueerror math log2 ninf self asserttruemath isnanmath log2nan requiresieee754 log2 is not accurate enough on mac os x tiger 10 4 support requiresmacver10 5 def testlog2exactself check that we get exact equality for log2 of powers of 2 actual math log2math ldexp1 0 n for n in range1074 1024 expected floatn for n in range1074 1024 self assertequalactual expected def testlog10self self assertraisestypeerror math log10 self ftest log100 1 math log100 1 1 self ftest log101 math log101 0 self ftest log1010 math log1010 1 self ftest log10101000 math log10101000 1000 0 self assertraisesvalueerror math log10 1 5 self assertraisesvalueerror math log10 101000 self assertraisesvalueerror math log10 ninf self assertequalmath loginf inf self asserttruemath isnanmath log10nan def testsumprodself sumprod math sumprod decimal decimal decimal fraction fractions fraction core functionality self assertequalsumproditer10 20 30 1 2 3 140 self assertequalsumprod1 5 2 5 3 5 4 5 16 5 self assertequalsumprod 0 self assertequalsumprod1 1 1 self assertequalsumprod1 1 1 type preservation and coercion for v in 10 20 30 1 5 2 5 fraction3 5 fraction4 5 decimal3 5 decimal4 5 2 5 10 floatint 2 5 fraction3 5 floatfraction 25 fraction3 5 intfraction 25 decimal4 5 intdecimal for p q in v v v v 1 with self subtestpp qq expected sumpi qi for pi qi in zipp q stricttrue actual sumprodp q self assertequalexpected actual self assertequaltypeexpected typeactual bad arguments self assertraisestypeerror sumprod no args self assertraisestypeerror sumprod one arg self assertraisestypeerror sumprod three args self assertraisestypeerror sumprod none 10 noniterable self assertraisestypeerror sumprod 10 none noniterable self assertraisestypeerror sumprod x 1 0 uneven lengths self assertraisesvalueerror sumprod 10 20 30 self assertraisesvalueerror sumprod 10 20 30 overflows self assertequalsumprod1020 1 1020 self assertequalsumprod1 1020 1020 self assertequalsumprod1010 1010 1020 self assertequalsumprod107105 107105 1019 self assertraisesoverflowerror sumprod 101000 1 0 self assertraisesoverflowerror sumprod 1 0 101000 error in iterator def raiseaftern for i in rangen yield i raise runtimeerror with self assertraisesruntimeerror sumprodrange10 raiseafter5 with self assertraisesruntimeerror sumprodraiseafter5 range10 from test testiter import basiciterclass self assertequalsumprodbasiciterclass1 1 0 self assertequalsumprod1 basiciterclass1 0 error in multiplication class badmultiply def mulself other raise runtimeerror def rmulself other raise runtimeerror with self assertraisesruntimeerror sumprod10 badmultiply 30 1 2 3 with self assertraisesruntimeerror sumprod1 2 3 10 badmultiply 30 error in addition with self assertraisestypeerror sumprod abc 3 5 10 with self assertraisestypeerror sumprod5 10 abc 3 special values should give the same as the pure python recipe self assertequalsumprod10 1 math inf 20 2 30 3 math inf self assertequalsumprod10 1 math inf math inf 30 3 math inf self assertequalsumprod10 1 math inf math inf math inf math inf self assertequalsumprod10 1 math inf 20 2 30 3 math inf self asserttruemath isnansumprod10 1 math inf math inf math inf self asserttruemath isnansumprod10 1 math nan 20 2 30 3 self asserttruemath isnansumprod10 1 math inf math nan 30 3 self asserttruemath isnansumprod10 1 math inf 20 3 math nan error cases that arose during development args 5 5 10 1 5 4611686018427387904 2305843009213693952 self assertequalsumprodargs 0 0 requiresieee754 unittest skipifhavedoublerounding sumprod accuracy not guaranteed on machines with double rounding support cpythononly other implementations may choose a different algorithm def testsumprodaccuracyself sumprod math sumprod self assertequalsumprod0 1 10 110 1 0 self assertequalsumprod0 1 20 true false 10 1 0 self assertequalsumprodtrue false 10 0 1 20 1 0 self assertequalsumprod1 0 10e100 1 0 10e100 1 04 2 0 support requiresresource cpu def testsumprodstressself sumprod math sumprod product itertools product decimal decimal decimal fraction fractions fraction class intint def addself other return intintself intother def mulself other return intintself intother radd add rmul mul def reprself return f intintself class fltfloat def addself other return intintself intother def mulself other return intintself intother radd add rmul mul def reprself return f fltintself def baselinesumprodp q total 0 for pi qi in zipp q stricttrue total pi qi return total def runfunc args make comparing functions easier returns error status type and result try result funcargs except assertionerror nameerror raise except exception as e return typee none none return none typeresult reprresult pools 5 10 220 231 240 261 262 280 1 5 int7 5 25 3 5 4 75 11 25 400 5 0 046875 0 25 1 0 0 078125 19 02500 1121000 321500 172333 5 25 3 25 3 02333 3 2513 3 75 2 5 1 5 float inf float inf float nan 14 9 34j flt13 0 0 13 25 4 25 decimal 10 5 decimal 2 25 fraction13 8 fraction11 16 4 75 0 125j 97 41 int3 decimal 6 125 decimal 12 375 decimal 2 75 decimal0 decimal inf decimal inf decimal nan 12 13 5 2 0 1000 1121000 3 7 37232 22537 22538 22513 7 2 0 510 5 2 0 520 17 19 0 6 25 11 25 3 75 0 625 23 375 true false 7 int5 for pool in pools for size in range4 for args1 in productpool repeatsize for args2 in productpool repeatsize args args1 args2 self assertequal runbaselinesumprod args runsumprod args args requiresieee754 unittest skipifhavedoublerounding sumprod accuracy not guaranteed on machines with double rounding support cpythononly other implementations may choose a different algorithm support requiresresource cpu def testsumprodextendedprecisionaccuracyself import operator from fractions import fraction from itertools import starmap from collections import namedtuple from math import log2 exp2 fabs from random import choices uniform shuffle from statistics import median dotexample namedtuple dotexample x y targetsumprod condition def dotexactx y vec1 mapfraction x vec2 mapfraction y return sumstarmapoperator mul zipvec1 vec2 stricttrue def conditionx y return 2 0 dotexactmapabs x mapabs y absdotexactx y def linspacelo hi n width hi lo n 1 return lo width i for i in rangen def gendotn c assert n 6 n2 n 2 x 0 0 n y 0 0 n b log2c first half with exponents from 0 to b2 and random ints in between e choicesrangeintb2 kn2 e0 intb 2 1 e1 0 0 x n2 uniform1 0 1 0 exp2p for p in e y n2 uniform1 0 1 0 exp2p for p in e second half e listmapround linspaceb2 0 0 nn2 for i in rangen2 n xi uniform1 0 1 0 exp2ei n2 yi uniform1 0 1 0 exp2ei n2 dotexactx y xi shuffle pairs listzipx y shufflepairs x y zippairs return dotexamplex y dotexactx y conditionx y def relativeerrorres ex x y targetsumprod condition ex n dotexactlistx res listy 1 return fabsn targetsumprod def trialdotfunc c n ex gendot10 c res dotfuncex x ex y return relativeerrorres ex times 1000 number of trials n 20 length of vectors c 1e30 target condition number if the following test fails it means that the c math library implementation of fma is not compliant with the c99 standard and is inaccurate to solve this problem make a new build with the symbol unreliablefma defined that will enable a slower but accurate code path that avoids the fma call relativeerr mediantrialmath sumprod c n for i in rangetimes self assertlessrelativeerr 1e16 def testmodfself self assertraisestypeerror math modf def testmodfname result expected v1 v2 e1 e2 result expected if absv1e1 eps or absv2e2 self fail s returned r expected r name result expected testmodf modf1 5 math modf1 5 0 5 1 0 testmodf modf1 5 math modf1 5 0 5 1 0 self assertequalmath modfinf 0 0 inf self assertequalmath modfninf 0 0 ninf modfnan math modfnan self asserttruemath isnanmodfnan0 self asserttruemath isnanmodfnan1 def testpowself self assertraisestypeerror math pow self ftest pow0 1 math pow0 1 0 self ftest pow1 0 math pow1 0 1 self ftest pow2 1 math pow2 1 2 self ftest pow2 1 math pow2 1 0 5 self assertequalmath powinf 1 inf self assertequalmath powninf 1 ninf self assertequalmath pow1 inf 1 self assertequalmath pow1 ninf 1 self asserttruemath isnanmath pownan 1 self asserttruemath isnanmath pow2 nan self asserttruemath isnanmath pow0 nan self assertequalmath pow1 nan 1 self assertraisesoverflowerror math pow 1e100 1e100 pow0 x self assertequalmath pow0 inf 0 self assertequalmath pow0 3 0 self assertequalmath pow0 2 3 0 self assertequalmath pow0 2 0 self assertequalmath pow0 0 1 self assertequalmath pow0 0 1 self assertraisesvalueerror math pow 0 2 self assertraisesvalueerror math pow 0 2 3 self assertraisesvalueerror math pow 0 3 self assertequalmath pow0 ninf inf self asserttruemath isnanmath pow0 nan powinf x self assertequalmath powinf inf inf self assertequalmath powinf 3 inf self assertequalmath powinf 2 3 inf self assertequalmath powinf 2 inf self assertequalmath powinf 0 1 self assertequalmath powinf 0 1 self assertequalmath powinf 2 0 self assertequalmath powinf 2 3 0 self assertequalmath powinf 3 0 self assertequalmath powinf ninf 0 self asserttruemath isnanmath powinf nan pow0 x self assertequalmath pow0 inf 0 self assertequalmath pow0 3 0 self assertequalmath pow0 2 3 0 self assertequalmath pow0 2 0 self assertequalmath pow0 0 1 self assertequalmath pow0 0 1 self assertraisesvalueerror math pow 0 2 self assertraisesvalueerror math pow 0 2 3 self assertraisesvalueerror math pow 0 3 self assertequalmath pow0 ninf inf self asserttruemath isnanmath pow0 nan powninf x self assertequalmath powninf inf inf self assertequalmath powninf 3 ninf self assertequalmath powninf 2 3 inf self assertequalmath powninf 2 inf self assertequalmath powninf 0 1 self assertequalmath powninf 0 1 self assertequalmath powninf 2 0 self assertequalmath powninf 2 3 0 self assertequalmath powninf 3 0 self assertequalmath powninf ninf 0 self asserttruemath isnanmath powninf nan pow1 x self assertequalmath pow1 inf 1 self assertequalmath pow1 3 1 self assertraisesvalueerror math pow 1 2 3 self assertequalmath pow1 2 1 self assertequalmath pow1 0 1 self assertequalmath pow1 0 1 self assertequalmath pow1 2 1 self assertraisesvalueerror math pow 1 2 3 self assertequalmath pow1 3 1 self assertequalmath pow1 ninf 1 self asserttruemath isnanmath pow1 nan pow1 x self assertequalmath pow1 inf 1 self assertequalmath pow1 3 1 self assertequalmath pow1 2 3 1 self assertequalmath pow1 2 1 self assertequalmath pow1 0 1 self assertequalmath pow1 0 1 self assertequalmath pow1 2 1 self assertequalmath pow1 2 3 1 self assertequalmath pow1 3 1 self assertequalmath pow1 ninf 1 self assertequalmath pow1 nan 1 powx 0 should be 1 for any x self assertequalmath pow2 3 0 1 self assertequalmath pow2 3 0 1 self assertequalmath pownan 0 1 self assertequalmath pow2 3 0 1 self assertequalmath pow2 3 0 1 self assertequalmath pownan 0 1 powx y is invalid if x is negative and y is not integral self assertraisesvalueerror math pow 1 2 3 self assertraisesvalueerror math pow 15 3 1 powx ninf self assertequalmath pow1 9 ninf 0 self assertequalmath pow1 1 ninf 0 self assertequalmath pow0 9 ninf inf self assertequalmath pow0 1 ninf inf self assertequalmath pow0 1 ninf inf self assertequalmath pow0 9 ninf inf self assertequalmath pow1 1 ninf 0 self assertequalmath pow1 9 ninf 0 powx inf self assertequalmath pow1 9 inf inf self assertequalmath pow1 1 inf inf self assertequalmath pow0 9 inf 0 self assertequalmath pow0 1 inf 0 self assertequalmath pow0 1 inf 0 self assertequalmath pow0 9 inf 0 self assertequalmath pow1 1 inf inf self assertequalmath pow1 9 inf inf powx y should work for x negative y an integer self ftest 2 3 math pow2 0 3 0 8 0 self ftest 2 2 math pow2 0 2 0 4 0 self ftest 2 1 math pow2 0 1 0 2 0 self ftest 2 0 math pow2 0 0 0 1 0 self ftest 2 0 math pow2 0 0 0 1 0 self ftest 2 1 math pow2 0 1 0 0 5 self ftest 2 2 math pow2 0 2 0 0 25 self ftest 2 3 math pow2 0 3 0 0 125 self assertraisesvalueerror math pow 2 0 0 5 self assertraisesvalueerror math pow 2 0 0 5 the following tests have been commented out since they don t really belong here the implementation of for floats is independent of the implementation of math pow self assertequal1nan 1 self assertequal1inf 1 self assertequal1ninf 1 self assertequal10 1 self assertequal1 nan 1 self assertequal1 inf 1 self assertequal1 ninf 1 self assertequal1 0 1 def testradiansself self assertraisestypeerror math radians self ftest radians180 math radians180 math pi self ftest radians90 math radians90 math pi2 self ftest radians45 math radians45 math pi4 self ftest radians0 math radians0 0 requiresieee754 def testremainderself from fractions import fraction def validatespecx y r fx fy fr fractionx fractiony fractionr r should not exceed y2 in absolute value self assertlessequalabsfr absfy2 x r should be an exact integer multiple of y n fx fr fy self assertequaln intn if absfr absfy2 if r y2 n should be even self assertequaln2 intn2 triples x y remainderx y in hexadecimal form testcases remainders modulo 1 showing the tiestoeven behaviour 4 0 1 0 0 3 8 1 0 8 3 0 1 0 0 2 8 1 0 8 2 0 1 0 0 1 8 1 0 8 1 0 1 0 0 0 8 1 0 8 0 0 1 0 0 0 0 1 0 0 0 8 1 0 8 1 0 1 0 0 1 8 1 0 8 2 0 1 0 0 2 8 1 0 8 3 0 1 0 0 3 8 1 0 8 4 0 1 0 0 reductions modulo 2pi 0x0 0p0 0x1 921fb54442d18p2 0x0 0p0 0x1 921fb54442d18p0 0x1 921fb54442d18p2 0x1 921fb54442d18p0 0x1 921fb54442d17p1 0x1 921fb54442d18p2 0x1 921fb54442d17p1 0x1 921fb54442d18p1 0x1 921fb54442d18p2 0x1 921fb54442d18p1 0x1 921fb54442d19p1 0x1 921fb54442d18p2 0x1 921fb54442d17p1 0x1 921fb54442d17p2 0x1 921fb54442d18p2 0x0 0000000000001p2 0x1 921fb54442d18p2 0x1 921fb54442d18p2 0x0p0 0x1 921fb54442d19p2 0x1 921fb54442d18p2 0x0 0000000000001p2 0x1 2d97c7f3321d1p3 0x1 921fb54442d18p2 0x1 921fb54442d14p1 0x1 2d97c7f3321d2p3 0x1 921fb54442d18p2 0x1 921fb54442d18p1 0x1 2d97c7f3321d3p3 0x1 921fb54442d18p2 0x1 921fb54442d14p1 0x1 921fb54442d17p3 0x1 921fb54442d18p2 0x0 0000000000001p3 0x1 921fb54442d18p3 0x1 921fb54442d18p2 0x0p0 0x1 921fb54442d19p3 0x1 921fb54442d18p2 0x0 0000000000001p3 0x1 f6a7a2955385dp3 0x1 921fb54442d18p2 0x1 921fb54442d14p1 0x1 f6a7a2955385ep3 0x1 921fb54442d18p2 0x1 921fb54442d18p1 0x1 f6a7a2955385fp3 0x1 921fb54442d18p2 0x1 921fb54442d14p1 0x1 1475cc9eedf00p5 0x1 921fb54442d18p2 0x1 921fb54442d10p1 0x1 1475cc9eedf01p5 0x1 921fb54442d18p2 0x1 921fb54442d10p1 symmetry with respect to signs 1 0 c 0 4 1 0 c 0 4 1 0 c 0 4 1 0 c 0 4 1 4 0 c 0 4 1 4 0 c 0 4 1 4 0 c 0 4 1 4 0 c 0 4 huge modulus to check that the underlying algorithm doesn t rely on 2 0 modulus being representable 0x1 dp1023 0x1 4p1023 0x0 9p1023 0x1 ep1023 0x1 4p1023 0x0 ap1023 0x1 fp1023 0x1 4p1023 0x0 9p1023 for case in testcases with self subtestcasecase xhex yhex expectedhex case split x float fromhexxhex y float fromhexyhex expected float fromhexexpectedhex validatespecx y expected actual math remainderx y cheap way of checking that the floats are as identical as we need them to be self assertequalactual hex expected hex test tiny subnormal modulus there s potential for getting the implementation wrong here for example by assuming that modulus2 is exactly representable tiny float fromhex 1p1074 min ve subnormal for n in range25 25 if n 0 continue y n tiny for m in range100 x m tiny actual math remainderx y validatespecx y actual actual math remainderx y validatespecx y actual special values nans should propagate as usual for value in nan 0 0 0 0 2 0 2 3 ninf inf self assertisnanmath remaindernan value self assertisnanmath remaindervalue nan remainderx inf is x for nonnan noninfinite x for value in 2 3 0 0 0 0 2 3 self assertequalmath remaindervalue inf value self assertequalmath remaindervalue ninf value remainderx 0 and remainderinfinity x for nonnan x are invalid operations according to ieee 7542008 7 2f and should raise for value in ninf 2 3 0 0 0 0 2 3 inf with self assertraisesvalueerror math remainderinf value with self assertraisesvalueerror math remainderninf value with self assertraisesvalueerror math remaindervalue 0 0 with self assertraisesvalueerror math remaindervalue 0 0 def testsinself self assertraisestypeerror math sin self ftest sin0 math sin0 0 self ftest sinpi2 math sinmath pi2 1 self ftest sinpi2 math sinmath pi2 1 try self asserttruemath isnanmath sininf self asserttruemath isnanmath sinninf except valueerror self assertraisesvalueerror math sin inf self assertraisesvalueerror math sin ninf self asserttruemath isnanmath sinnan def testsinhself self assertraisestypeerror math sinh self ftest sinh0 math sinh0 0 self ftest sinh12cosh12 math sinh12math cosh12 1 self ftest sinh1sinh1 math sinh1math sinh1 0 self assertequalmath sinhinf inf self assertequalmath sinhninf ninf self asserttruemath isnanmath sinhnan def testsqrtself self assertraisestypeerror math sqrt self ftest sqrt0 math sqrt0 0 self ftest sqrt0 math sqrt0 0 0 0 self ftest sqrt2 5 math sqrt2 5 1 5811388300841898 self ftest sqrt0 25 math sqrt0 25 0 5 self ftest sqrt25 25 math sqrt25 25 5 024937810560445 self ftest sqrt1 math sqrt1 1 self ftest sqrt4 math sqrt4 2 self assertequalmath sqrtinf inf self assertraisesvalueerror math sqrt 1 self assertraisesvalueerror math sqrt ninf self asserttruemath isnanmath sqrtnan def testtanself self assertraisestypeerror math tan self ftest tan0 math tan0 0 self ftest tanpi4 math tanmath pi4 1 self ftest tanpi4 math tanmath pi4 1 try self asserttruemath isnanmath taninf self asserttruemath isnanmath tanninf except self assertraisesvalueerror math tan inf self assertraisesvalueerror math tan ninf self asserttruemath isnanmath tannan def testtanhself self assertraisestypeerror math tanh self ftest tanh0 math tanh0 0 self ftest tanh1tanh1 math tanh1math tanh1 0 abstolmath ulp1 self ftest tanhinf math tanhinf 1 self ftest tanhinf math tanhninf 1 self asserttruemath isnanmath tanhnan requiresieee754 def testtanhsignself check that tanh0 0 on ieee 754 systems self assertequalmath tanh0 0 self assertequalmath copysign1 math tanh0 math copysign1 0 def testtruncself self assertequalmath trunc1 1 self assertequalmath trunc1 1 self assertequaltypemath trunc1 int self assertequaltypemath trunc1 5 int self assertequalmath trunc1 5 1 self assertequalmath trunc1 5 1 self assertequalmath trunc1 999999 1 self assertequalmath trunc1 999999 1 self assertequalmath trunc0 999999 0 self assertequalmath trunc100 999 100 class testtrunc def truncself return 23 class floattruncfloat def truncself return 23 class testnotrunc pass class testbadtrunc trunc baddescr self assertequalmath trunctesttrunc 23 self assertequalmath truncfloattrunc 23 self assertraisestypeerror math trunc self assertraisestypeerror math trunc 1 2 self assertraisestypeerror math trunc floatlike23 5 self assertraisestypeerror math trunc testnotrunc self assertraisesvalueerror math trunc testbadtrunc def testisfiniteself self asserttruemath isfinite0 0 self asserttruemath isfinite0 0 self asserttruemath isfinite1 0 self asserttruemath isfinite1 0 self assertfalsemath isfinitefloatnan self assertfalsemath isfinitefloatinf self assertfalsemath isfinitefloatinf def testisnanself self asserttruemath isnanfloatnan self asserttruemath isnanfloatnan self asserttruemath isnanfloatinf 0 self assertfalsemath isnanfloatinf self assertfalsemath isnan0 self assertfalsemath isnan1 def testisinfself self asserttruemath isinffloatinf self asserttruemath isinffloatinf self asserttruemath isinf1e400 self asserttruemath isinf1e400 self assertfalsemath isinffloatnan self assertfalsemath isinf0 self assertfalsemath isinf1 def testnanconstantself math nan must be a quiet nan with positive sign bit self asserttruemath isnanmath nan self assertequalmath copysign1 math nan 1 def testinfconstantself self asserttruemath isinfmath inf self assertgreatermath inf 0 0 self assertequalmath inf floatinf self assertequalmath inf floatinf redflag 16oct2000 tim while 2 0 is more consistent about exceptions than previous releases it still fails this part of the test on some platforms for now we only run testexceptions in verbose mode so that this isn t normally tested unittest skipunlessverbose requires verbose mode def testexceptionsself try x math exp1000000000 except mathmodule c is failing to weed out underflows from libm or we ve got an fp format with huge dynamic range self failunderflowing exp should not have raised an exception if x 0 self failunderflowing exp should have returned 0 if this fails probably using a strict ieee754 conforming libm and x is inf afterwards but python wants overflows detected by default try x math exp1000000000 except overflowerror pass else self failoverflowing exp didn t trigger overflowerror if this fails it could be a puzzle one odd possibility is that mathmodule c s macros are getting confused while comparing inf hugeval to a nan and artificially setting errno to erange as a result and so raising overflowerror instead try x math sqrt1 0 except valueerror pass else self failsqrt1 didn t raise valueerror requiresieee754 def testtestfileself some tests need to be skipped on ancient os x versions see issue 27953 skipontiger tan0064 osxversion none if sys platform darwin versiontxt platform macver0 try osxversion tuplemapint versiontxt split except valueerror pass failfmt r failures for id fn ar ai er ei flags in parsetestfiletestfile skip if either the input or result is complex if ai 0 0 or ei 0 0 continue if fn in rect polar no real versions of rect polar continue skip certain tests on os x 10 4 if osxversion is not none and osxversion 10 5 if id in skipontiger continue func getattrmath fn if invalid in flags or dividebyzero in flags er valueerror elif overflow in flags er overflowerror try result funcar except valueerror result valueerror except overflowerror result overflowerror default tolerances ulptol abstol 5 0 0 failure resultchecker result ulptol abstol if failure is none continue msg failfmt formatid fn ar failure failures appendmsg if failures self fail failures in testtestfile n n joinfailures requiresieee754 def testmtestfileself failfmt r failures for id fn arg expected flags in parsemtestfilemathtestcases func getattrmath fn if invalid in flags or dividebyzero in flags expected valueerror elif overflow in flags expected overflowerror try got funcarg except valueerror got valueerror except overflowerror got overflowerror default tolerances ulptol abstol 5 0 0 exceptions to the defaults if fn gamma experimental results on one platform gave an accuracy of 10 ulps across the entire float domain we weaken that to require 20 ulp accuracy ulptol 20 elif fn lgamma we use a weaker accuracy test for lgamma lgamma only achieves an absolute error of a few multiples of the machine accuracy in general abstol 1e15 elif fn erfc and arg 0 0 erfc has lessthanideal accuracy for large arguments x 25 or so mainly due to the error involved in computing expxx observed between cpython and mpmath at 25 dp x 0 err 2 ulp 0 x 1 err 10 ulp 1 x 10 err 100 ulp 10 x 20 err 300 ulp 20 x 600 ulp if arg 1 0 ulptol 10 elif arg 10 0 ulptol 100 else ulptol 1000 failure resultcheckexpected got ulptol abstol if failure is none continue msg failfmt formatid fn arg failure failures appendmsg if failures self fail failures in testmtestfile n n joinfailures def testprodself from fractions import fraction as f prod math prod self assertequalprod 1 self assertequalprod start5 5 self assertequalprodlistrange2 8 5040 self assertequalproditerlistrange2 8 5040 self assertequalprodrange1 10 start10 3628800 self assertequalprod1 2 3 4 5 120 self assertequalprod1 0 2 0 3 0 4 0 5 0 120 0 self assertequalprod1 2 3 4 0 5 0 120 0 self assertequalprod1 0 2 0 3 0 4 5 120 0 self assertequalprod1 f3 2 1 5 error in multiplication class badmultiply def rmulself other raise runtimeerror with self assertraisesruntimeerror prod10 badmultiply test overflow in fastpath for integers self assertequalprod1 1 232 1 1 232 test overflow in fastpath for floats self assertequalprod1 0 1 0 232 1 1 float232 self assertraisestypeerror prod self assertraisestypeerror prod 42 self assertraisestypeerror prod a b c self assertraisestypeerror prod a b c start self assertraisestypeerror prod b a b c startb values bytearrayb a bytearrayb b self assertraisestypeerror prod values startbytearrayb self assertraisestypeerror prod 1 2 3 self assertraisestypeerror prod 2 3 self assertraisestypeerror prod 2 32 start2 3 self assertraisestypeerror prod 1 2 3 start some odd cases self assertequalprod2 3 start ab abababababab self assertequalprod2 3 start1 2 1 2 1 2 1 2 1 2 1 2 1 2 self assertequalprod start2 3 2 3 with self assertraisestypeerror prod10 20 1 start is a keywordonly argument self assertequalprod0 1 2 3 0 self assertequalprod1 0 2 3 0 self assertequalprod1 2 3 0 0 def naiveproditerable start1 for elem in iterable start elem return start big integers iterable range1 10000 self assertequalproditerable naiveproditerable iterable range10000 1 self assertequalproditerable naiveproditerable iterable range1000 1000 self assertequalproditerable 0 big floats iterable floatx for x in range1 1000 self assertequalproditerable naiveproditerable iterable floatx for x in range1000 1 self assertequalproditerable naiveproditerable iterable floatx for x in range1000 1000 self assertisnanproditerable float tests self assertisnanprod1 2 3 floatnan 2 3 self assertisnanprod1 0 floatnan 2 3 self assertisnanprod1 floatnan 0 3 self assertisnanprod1 floatinf floatnan 3 self assertisnanprod1 floatinf floatnan 3 self assertisnanprod1 floatnan floatinf 3 self assertisnanprod1 floatnan floatinf 3 self assertequalprod1 2 3 float inf 3 4 float inf self assertequalprod1 2 3 float inf 3 4 float inf self assertisnanprod1 2 0 float inf 3 4 self assertisnanprod1 2 0 float inf 3 4 self assertisnanprod1 2 3 float inf 3 0 3 self assertisnanprod1 2 3 float inf 3 0 2 type preservation self assertequaltypeprod1 2 3 4 5 6 int self assertequaltypeprod1 2 0 3 4 5 6 float self assertequaltypeprodrange1 10000 int self assertequaltypeprodrange1 10000 start1 0 float self assertequaltypeprod1 decimal decimal2 0 3 4 5 6 decimal decimal def testpermself perm math perm factorial math factorial test if factorial definition is satisfied for n in range500 for k in rangen 1 if n 100 else range30 if n 200 else range10 self assertequalpermn k factorialn factorialn k test for pascal s identity for n in range1 100 for k in range1 n self assertequalpermn k permn 1 k 1 k permn 1 k test corner cases for n in range1 100 self assertequalpermn 0 1 self assertequalpermn 1 n self assertequalpermn n factorialn test one argument form for n in range20 self assertequalpermn factorialn self assertequalpermn none factorialn raises typeerror if any argument is noninteger or argument count is not 1 or 2 self assertraisestypeerror perm 10 1 0 self assertraisestypeerror perm 10 decimal decimal1 0 self assertraisestypeerror perm 10 1 self assertraisestypeerror perm 10 0 1 self assertraisestypeerror perm decimal decimal10 0 1 self assertraisestypeerror perm 10 1 self assertraisestypeerror perm self assertraisestypeerror perm 10 1 3 self assertraisestypeerror perm raises value error if not k or n are negative numbers self assertraisesvalueerror perm 1 1 self assertraisesvalueerror perm 21000 1 self assertraisesvalueerror perm 1 1 self assertraisesvalueerror perm 1 21000 returns zero if k is greater than n self assertequalperm1 2 0 self assertequalperm1 21000 0 n 21000 self assertequalpermn 0 1 self assertequalpermn 1 n self assertequalpermn 2 n n1 if support checkimpldetailcpythontrue self assertraisesoverflowerror perm n n for n k in true true true false false false self assertequalpermn k 1 self assertistypepermn k int self assertequalpermintsubclass5 intsubclass2 20 self assertequalpermmyindexable5 myindexable2 20 for k in range3 self assertistypepermintsubclass5 intsubclassk int self assertistypepermmyindexable5 myindexablek int def testcombself comb math comb factorial math factorial test if factorial definition is satisfied for n in range500 for k in rangen 1 if n 100 else range30 if n 200 else range10 self assertequalcombn k factorialn factorialk factorialn k test for pascal s identity for n in range1 100 for k in range1 n self assertequalcombn k combn 1 k 1 combn 1 k test corner cases for n in range100 self assertequalcombn 0 1 self assertequalcombn n 1 for n in range1 100 self assertequalcombn 1 n self assertequalcombn n 1 n test symmetry for n in range100 for k in rangen 2 self assertequalcombn k combn n k raises typeerror if any argument is noninteger or argument count is not 2 self assertraisestypeerror comb 10 1 0 self assertraisestypeerror comb 10 decimal decimal1 0 self assertraisestypeerror comb 10 1 self assertraisestypeerror comb 10 0 1 self assertraisestypeerror comb decimal decimal10 0 1 self assertraisestypeerror comb 10 1 self assertraisestypeerror comb 10 self assertraisestypeerror comb 10 1 3 self assertraisestypeerror comb raises value error if not k or n are negative numbers self assertraisesvalueerror comb 1 1 self assertraisesvalueerror comb 21000 1 self assertraisesvalueerror comb 1 1 self assertraisesvalueerror comb 1 21000 returns zero if k is greater than n self assertequalcomb1 2 0 self assertequalcomb1 21000 0 n 21000 self assertequalcombn 0 1 self assertequalcombn 1 n self assertequalcombn 2 n n1 2 self assertequalcombn n 1 self assertequalcombn n1 n self assertequalcombn n2 n n1 2 if support checkimpldetailcpythontrue self assertraisesoverflowerror comb n n2 for n k in true true true false false false self assertequalcombn k 1 self assertistypecombn k int self assertequalcombintsubclass5 intsubclass2 10 self assertequalcombmyindexable5 myindexable2 10 for k in range3 self assertistypecombintsubclass5 intsubclassk int self assertistypecombmyindexable5 myindexablek int requiresieee754 def testnextafterself around 252 and 263 self assertequalmath nextafter4503599627370496 0 inf 4503599627370495 5 self assertequalmath nextafter4503599627370496 0 inf 4503599627370497 0 self assertequalmath nextafter9223372036854775808 0 0 0 9223372036854774784 0 self assertequalmath nextafter9223372036854775808 0 0 0 9223372036854774784 0 around 1 0 self assertequalmath nextafter1 0 inf float fromhex 0x1 fffffffffffffp1 self assertequalmath nextafter1 0 inf float fromhex 0x1 0000000000001p0 self assertequalmath nextafter1 0 inf steps1 float fromhex 0x1 fffffffffffffp1 self assertequalmath nextafter1 0 inf steps1 float fromhex 0x1 0000000000001p0 self assertequalmath nextafter1 0 inf steps3 float fromhex 0x1 ffffffffffffdp1 self assertequalmath nextafter1 0 inf steps3 float fromhex 0x1 0000000000003p0 x y y is returned for steps in range1 5 self assertequalmath nextafter2 0 2 0 stepssteps 2 0 self assertequalsignmath nextafter0 0 0 0 stepssteps 0 0 self assertequalsignmath nextafter0 0 0 0 stepssteps 0 0 around 0 0 smallestsubnormal sys floatinfo min sys floatinfo epsilon self assertequalmath nextafter0 0 inf smallestsubnormal self assertequalmath nextafter0 0 inf smallestsubnormal self assertequalmath nextafter0 0 inf smallestsubnormal self assertequalmath nextafter0 0 inf smallestsubnormal self assertequalsignmath nextaftersmallestsubnormal 0 0 0 0 self assertequalsignmath nextaftersmallestsubnormal 0 0 0 0 self assertequalsignmath nextaftersmallestsubnormal 0 0 0 0 self assertequalsignmath nextaftersmallestsubnormal 0 0 0 0 around infinity largestnormal sys floatinfo max self assertequalmath nextafterinf 0 0 largestnormal self assertequalmath nextafterinf 0 0 largestnormal self assertequalmath nextafterlargestnormal inf inf self assertequalmath nextafterlargestnormal inf inf nan self assertisnanmath nextafternan 1 0 self assertisnanmath nextafter1 0 nan self assertisnanmath nextafternan nan self assertequal1 0 math nextafter1 0 inf steps0 with self assertraisesvalueerror math nextafter1 0 inf steps1 requiresieee754 def testulpself self assertequalmath ulp1 0 sys floatinfo epsilon use int int rather than float int to not rely on pow accuracy self assertequalmath ulp2 52 1 0 self assertequalmath ulp2 53 2 0 self assertequalmath ulp2 64 4096 0 min and max self assertequalmath ulp0 0 sys floatinfo min sys floatinfo epsilon self assertequalmath ulpfloatmax floatmax math nextafterfloatmax inf special cases self assertequalmath ulpinf inf self assertisnanmath ulpmath nan negative number ulpx ulpx for x in 0 0 1 0 2 52 2 64 inf with self subtestxx self assertequalmath ulpx math ulpx def testissue39871self a systemerror should not be raised if the first arg to atan2 copysign or remainder cannot be converted to a float class f def floatself self converted true 10 for func in math atan2 math copysign math remainder y f with self assertraisestypeerror funcnot a number y there should not have been any attempt to convert the second argument to a float self assertfalsegetattry converted false def testinputexceptionsself self assertraisestypeerror math exp spam self assertraisestypeerror math erf spam self assertraisestypeerror math atan2 spam 1 0 self assertraisestypeerror math atan2 1 0 spam self assertraisestypeerror math atan2 1 0 self assertraisestypeerror math atan2 1 0 2 0 3 0 custom assertions def assertisnanself value if not math isnanvalue self failexpected a nan got r formatvalue def assertequalsignself x y self assertequalx y self assertequalmath copysign1 0 x math copysign1 0 y class isclosetestsunittest testcase isclose math isclose subclasses should override this def assertiscloseself a b args kwargs self asserttrueself isclosea b args kwargs msgs and s should be close a b def assertisnotcloseself a b args kwargs self assertfalseself isclosea b args kwargs msgs and s should not be close a b def assertallcloseself examples args kwargs for a b in examples self assertisclosea b args kwargs def assertallnotcloseself examples args kwargs for a b in examples self assertisnotclosea b args kwargs def testnegativetolerancesself valueerror should be raised if either tolerance is less than zero with self assertraisesvalueerror self assertisclose1 1 reltol1e100 with self assertraisesvalueerror self assertisclose1 1 reltol1e100 abstol1e10 def testidenticalself identical values must test as close identicalexamples 2 0 2 0 0 1e200 0 1e200 1 123e300 1 123e300 12345 12345 0 0 0 0 0 345678 345678 self assertallcloseidenticalexamples reltol0 0 abstol0 0 def testeightdecimalplacesself examples that are close to 1e8 but not 1e9 eightdecimalplacesexamples 1e8 1e8 1 1e8 1 000000009e8 1 12345678 1 12345679 self assertallcloseeightdecimalplacesexamples reltol1e8 self assertallnotcloseeightdecimalplacesexamples reltol1e9 def testnearzeroself values close to zero nearzeroexamples 1e9 0 0 1e9 0 0 1e150 0 0 these should not be close to any reltol self assertallnotclosenearzeroexamples reltol0 9 these should be close to abstol1e8 self assertallclosenearzeroexamples abstol1e8 def testidenticalinfiniteself these are close regardless of tolerance i e they are equal self assertiscloseinf inf self assertiscloseinf inf abstol0 0 self assertiscloseninf ninf self assertiscloseninf ninf abstol0 0 def testinfninfnanself these should never be close following ieee 754 rules for equality notcloseexamples nan nan nan 1e100 1e100 nan inf nan nan inf inf ninf inf 1 0 1 0 inf inf 1e308 1e308 inf use largest reasonable tolerance self assertallnotclosenotcloseexamples abstol0 999999999999999 def testzerotoleranceself test with zero tolerance zerotolerancecloseexamples 1 0 1 0 3 4 3 4 1e300 1e300 self assertallclosezerotolerancecloseexamples reltol0 0 zerotolerancenotcloseexamples 1 0 1 000000000000001 0 99999999999999 1 0 1 0e200 999999999999999e200 self assertallnotclosezerotolerancenotcloseexamples reltol0 0 def testasymmetryself test the asymmetry example from pep 485 self assertallclose9 10 10 9 reltol0 1 def testintegersself test with integer values integerexamples 100000001 100000000 123456789 123456788 self assertallcloseintegerexamples reltol1e8 self assertallnotcloseintegerexamples reltol1e9 def testdecimalsself test with decimal values from decimal import decimal decimalexamples decimal 1 00000001 decimal 1 0 decimal 1 00000001e20 decimal 1 0e20 decimal 1 00000001e100 decimal 1 0e100 decimal 1 00000001e20 decimal 1 0e20 self assertallclosedecimalexamples reltol1e8 self assertallnotclosedecimalexamples reltol1e9 def testfractionsself test with fraction values from fractions import fraction fractionexamples fraction1 100000000 1 fraction1 fraction100000001 fraction100000000 fraction108 1 1028 fraction1 1020 self assertallclosefractionexamples reltol1e8 self assertallnotclosefractionexamples reltol1e9 def loadtestsloader tests pattern from doctest import docfilesuite tests addtestdocfilesuiteos path joinmathdata ieee754 txt return tests if name main unittest main python test set math module xxxx should not do tests around zero only detect evidence of double rounding fsum is not always correctly rounded on machines that suffer from double rounding use temporary values to defeat peephole optimizer locate file with test values convert a non nan float x to an integer in such a way that adjacent floats are converted to adjacent integers then abs ulps x ulps y gives the difference in ulps between two floats the results from this function will only make sense on platforms where native doubles are represented in ieee 754 binary64 format note 0 0 and 0 0 are converted to 0 and 1 respectively here s a pure python version of the math factorial algorithm for documentation and comparison purposes formula factorial n factorial_odd_part n n count_set_bits n where factorial_odd_part n product_ i 0 product_ 0 j n i j odd j the outer product above is an infinite product but once i n bit_length n i 1 and the corresponding term of the product is empty so only the finitely many terms for 0 i n bit_length contribute anything we iterate downwards from i n bit_length 1 to i 0 the inner product in the formula above starts at 1 for i n bit_length for each i n bit_length we get the inner product for i from that for i 1 by multiplying by all j in n i 1 j n i j odd in python terms this set is range n i 1 1 1 n i 1 1 2 number of 1 bits in binary expansion of a nonnnegative integer product of integers in range start stop 2 computed recursively start and stop should both be odd with start stop factorial of nonnegative integer n via binary split factorial formula described at http www luschny de math factorial binarysplitfact html given finite floats expected and got check that they re approximately equal to within the given number of ulps or the given absolute tolerance whichever is bigger returns none on success and an error message on failure succeed if either abs_error abs_tol or ulp_error ulp_tol parse a file with test values starts a comment blank lines or lines containing only a comment are ignored other lines are expected to have the form id fn arg expected flag strip comments and skip blank lines parse a file with test values empty lines or lines starting with are ignored yields id fn arg_real arg_imag exp_real exp_imag skip comment lines and blank lines common logic of mathtests ftest test_testcases test_mtestcases compare arguments expected and got as floats if either is a float using a tolerance expressed in multiples of ulp expected or absolutely if given and greater as a convenience when neither argument is a float and for non finite floats exact equality is demanded also nan nan as far as this function is concerned returns none on success and an error message on failure check exactly equal applies also to strings representing exceptions turn mixed float and int comparison e g floor to all float pass since both nan we already know they re not equal drop through to failure both are finite floats now are they close enough arguments are not equal and if numeric are too far apart class providing an __index__ method compare arguments expected and got as floats if either is a float using a tolerance expressed in multiples of ulp expected or absolutely whichever is greater as a convenience when neither argument is a float and for non finite floats exact equality is demanded also nan nan in this function ref abramowitz stegun dover 1965 math atan2 0 x math atan2 0 x math atan2 inf x math atan2 ninf x math atan2 finite x math atan2 finite x math atan2 nan x self assertequal math ceil inf inf self assertequal math ceil ninf ninf self asserttrue math isnan math ceil nan copysign should let us distinguish signs of zeros and of infinities copysign inf nan may be inf or it may be ninf since we don t know whether the sign bit of nan is set on any given platform similarly copysign 2 nan could be 2 or 2 thanks to lambert other implementations may place different upper bounds currently raises overflowerror for inputs that are too large to fit into a c long self assertequal math ceil inf inf self assertequal math ceil ninf ninf self asserttrue math isnan math floor nan math fsum relies on exact rounding for correct operation there s a known problem with ia32 floating point that causes inexact rounding in some situations and will cause the math fsum tests below to fail see issue 2937 on non ieee 754 platforms and on ieee 754 platforms that exhibit the problem described in issue 2937 we simply skip the whole test python version of math fsum for comparison uses a different algorithm based on frexp ldexp and integer arithmetic full precision summation compute sum iterable without any intermediate accumulation of error based on the lsum function at http code activestate com recipes 393090 round tmant 2 texp to a float the original recipe used float str tmant 2 0 texp for this but that s a little unsafe because str float conversion can t be relied upon to do correct rounding on all platforms exercise code for resizing partials array telescoping sum with exact differences due to sterbenz test different numbers of arguments from zero to five against a straightforward pure python implementation test allowable types those with __float__ test corner cases max input is zero negative input negative input convert negative zero to positive zero handling of moving max to the end test handling of bad arguments reject keyword args reject values without __float__ any infinity gives positive infinity if no infinity any nan gives a nan verify scaling for extremely large values verify scaling for extremely small values verify improved accuracy in cases that were known to be inaccurate the new algorithm s accuracy depends on ieee 754 arithmetic guarantees on having the usual round half even rounding mode on the system not having double rounding due to extended precision and on the compiler maintaining the specified order of operations this test is known to succeed on most of our builds if it fails some build we either need to add another skipif if the cause is identifiable otherwise we can remove this test entirely cases with a 1 ulp error in python 3 7 compiled with clang cases with 2 ulp error in python 3 8 cases with 1 ulp error in version fff3c28052e6b0 simple exact cases test different numbers of arguments from zero to nine against a straightforward pure python implementation test non tuple inputs test allowable types those with __float__ test corner cases distance with self is zero zero dimensional case convert negative zero to positive zero convert negative zero to positive zero handling of moving max to the end verify tuple subclasses are allowed test handling of bad arguments reject keyword args too few args too many args scalars not allowed reject values without __float__ check dimension agree check dimension agree rejects invalid types verify that the one dimensional case is equivalent to abs test special values any infinite difference gives positive infinity if no infinity any nan gives a nan verify scaling for extremely large values verify scaling for extremely small values gh 98897 check for error handling does not leak memory test a variety of inputs large and small negative values integer like things non integer like things large second argument check some integer values large integer values log2 is not accurate enough on mac os x tiger 10 4 check that we get exact equality for log2 of powers of 2 core functionality type preservation and coercion float int float fraction int fraction int decimal bad arguments no args one arg three args non iterable non iterable uneven lengths overflows error in iterator error in multiplication error in addition special values should give the same as the pure python recipe error cases that arose during development other implementations may choose a different algorithm this defines the target behavior including expections and special values however it is subject to rounding errors so float inputs should be exactly representable with only a few bits other implementations may choose a different algorithm algorithm 6 1 gendot works as follows the condition number 5 7 of the dot product xt y is proportional to the degree of cancellation in order to achieve a prescribed cancellation we generate the first half of the vectors x and y randomly within a large exponent range this range is chosen according to the anticipated condition number the second half of x and y is then constructed choosing xi randomly with decreasing exponent and calculating yi such that some cancellation occurs finally we permute the vectors x y randomly and calculate the achieved condition number first half with exponents from 0 to _b 2_ and random ints in between second half shuffle number of trials length of vectors target condition number if the following test fails it means that the c math library implementation of fma is not compliant with the c99 standard and is inaccurate to solve this problem make a new build with the symbol unreliable_fma defined that will enable a slower but accurate code path that avoids the fma call pow 0 x pow inf x pow 0 x pow ninf x pow 1 x pow 1 x pow x 0 should be 1 for any x pow x y is invalid if x is negative and y is not integral pow x ninf pow x inf pow x y should work for x negative y an integer the following tests have been commented out since they don t really belong here the implementation of for floats is independent of the implementation of math pow self assertequal 1 nan 1 self assertequal 1 inf 1 self assertequal 1 ninf 1 self assertequal 1 0 1 self assertequal 1 nan 1 self assertequal 1 inf 1 self assertequal 1 ninf 1 self assertequal 1 0 1 check that r matches remainder x y according to the ieee 754 specification assumes that x y and r are finite and y is nonzero r should not exceed y 2 in absolute value x r should be an exact integer multiple of y if r y 2 n should be even triples x y remainder x y in hexadecimal form remainders modulo 1 showing the ties to even behaviour reductions modulo 2 pi symmetry with respect to signs huge modulus to check that the underlying algorithm doesn t rely on 2 0 modulus being representable cheap way of checking that the floats are as identical as we need them to be test tiny subnormal modulus there s potential for getting the implementation wrong here for example by assuming that modulus 2 is exactly representable min ve subnormal special values nans should propagate as usual remainder x inf is x for non nan non infinite x remainder x 0 and remainder infinity x for non nan x are invalid operations according to ieee 754 2008 7 2 f and should raise check that tanh 0 0 on ieee 754 systems math nan must be a quiet nan with positive sign bit red_flag 16 oct 2000 tim while 2 0 is more consistent about exceptions than previous releases it still fails this part of the test on some platforms for now we only run test_exceptions in verbose mode so that this isn t normally tested mathmodule c is failing to weed out underflows from libm or we ve got an fp format with huge dynamic range if this fails probably using a strict ieee 754 conforming libm and x is inf afterwards but python wants overflows detected by default if this fails it could be a puzzle one odd possibility is that mathmodule c s macros are getting confused while comparing inf huge_val to a nan and artificially setting errno to erange as a result and so raising overflowerror instead some tests need to be skipped on ancient os x versions see issue 27953 skip if either the input or result is complex no real versions of rect polar skip certain tests on os x 10 4 default tolerances default tolerances exceptions to the defaults experimental results on one platform gave an accuracy of 10 ulps across the entire float domain we weaken that to require 20 ulp accuracy we use a weaker accuracy test for lgamma lgamma only achieves an absolute error of a few multiples of the machine accuracy in general erfc has less than ideal accuracy for large arguments x 25 or so mainly due to the error involved in computing exp x x observed between cpython and mpmath at 25 dp x 0 err 2 ulp 0 x 1 err 10 ulp 1 x 10 err 100 ulp 10 x 20 err 300 ulp 20 x 600 ulp error in multiplication test overflow in fast path for integers test overflow in fast path for floats some odd cases start is a keyword only argument big integers big floats float tests type preservation test if factorial definition is satisfied test for pascal s identity test corner cases test one argument form raises typeerror if any argument is non integer or argument count is not 1 or 2 raises value error if not k or n are negative numbers returns zero if k is greater than n test if factorial definition is satisfied test for pascal s identity test corner cases test symmetry raises typeerror if any argument is non integer or argument count is not 2 raises value error if not k or n are negative numbers returns zero if k is greater than n around 2 52 and 2 63 around 1 0 x y y is returned around 0 0 around infinity nan use int int rather than float int to not rely on pow accuracy min and max special cases negative number ulp x ulp x a systemerror should not be raised if the first arg to atan2 copysign or remainder cannot be converted to a float there should not have been any attempt to convert the second argument to a float custom assertions similar to assertequal but compare also the sign with copysign function useful to compare signed zeros subclasses should override this valueerror should be raised if either tolerance is less than zero identical values must test as close examples that are close to 1e 8 but not 1e 9 values close to zero these should not be close to any rel_tol these should be close to abs_tol 1e 8 these are close regardless of tolerance i e they are equal these should never be close following ieee 754 rules for equality use largest reasonable tolerance test with zero tolerance test the asymmetry example from pep 485 test with integer values test with decimal values test with fraction values
from test.support import verbose, requires_IEEE_754
from test import support
import unittest
import fractions
import itertools
import decimal
import math
import os
import platform
import random
import struct
import sys


eps = 1E-05
NAN = float('nan')
INF = float('inf')
NINF = float('-inf')
FLOAT_MAX = sys.float_info.max
FLOAT_MIN = sys.float_info.min



x, y = 1e16, 2.9999 
HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)


if __name__ == '__main__':
    file = sys.argv[0]
else:
    file = __file__
test_dir = os.path.dirname(file) or os.curdir
math_testcases = os.path.join(test_dir, 'mathdata', 'math_testcases.txt')
test_file = os.path.join(test_dir, 'mathdata', 'cmath_testcases.txt')


def to_ulps(x):
    
    n = struct.unpack('<q', struct.pack('<d', x))[0]
    if n < 0:
        n = ~(n+2**63)
    return n























def count_set_bits(n):
    
    return 1 + count_set_bits(n & n - 1) if n else 0

def partial_product(start, stop):
    
    numfactors = (stop - start) >> 1
    if not numfactors:
        return 1
    elif numfactors == 1:
        return start
    else:
        mid = (start + numfactors) | 1
        return partial_product(start, mid) * partial_product(mid, stop)

def py_factorial(n):
    
    inner = outer = 1
    for i in reversed(range(n.bit_length())):
        inner *= partial_product((n >> i + 1) + 1 | 1, (n >> i) + 1 | 1)
        outer *= inner
    return outer << (n - count_set_bits(n))

def ulp_abs_check(expected, got, ulp_tol, abs_tol):
    
    ulp_error = abs(to_ulps(expected) - to_ulps(got))
    abs_error = abs(expected - got)

    
    if abs_error <= abs_tol or ulp_error <= ulp_tol:
        return None
    else:
        fmt = ("error = {:.3g} ({:d} ulps); "
               "permitted error = {:.3g} or {:d} ulps")
        return fmt.format(abs_error, ulp_error, abs_tol, ulp_tol)

def parse_mtestfile(fname):
    
    with open(fname, encoding="utf-8") as fp:
        for line in fp:
            
            if '--' in line:
                line = line[:line.index('--')]
            if not line.strip():
                continue

            lhs, rhs = line.split('->')
            id, fn, arg = lhs.split()
            rhs_pieces = rhs.split()
            exp = rhs_pieces[0]
            flags = rhs_pieces[1:]

            yield (id, fn, float(arg), float(exp), flags)


def parse_testfile(fname):
    
    with open(fname, encoding="utf-8") as fp:
        for line in fp:
            
            if line.startswith('--') or not line.strip():
                continue

            lhs, rhs = line.split('->')
            id, fn, arg_real, arg_imag = lhs.split()
            rhs_pieces = rhs.split()
            exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
            flags = rhs_pieces[2:]

            yield (id, fn,
                   float(arg_real), float(arg_imag),
                   float(exp_real), float(exp_imag),
                   flags)


def result_check(expected, got, ulp_tol=5, abs_tol=0.0):
    
    

    
    if got == expected:
        return None

    failure = "not equal"

    
    if isinstance(expected, float) and isinstance(got, int):
        got = float(got)
    elif isinstance(got, float) and isinstance(expected, int):
        expected = float(expected)

    if isinstance(expected, float) and isinstance(got, float):
        if math.isnan(expected) and math.isnan(got):
            
            failure = None
        elif math.isinf(expected) or math.isinf(got):
            
            pass
        else:
            
            failure = ulp_abs_check(expected, got, ulp_tol, abs_tol)

    
    if failure is not None:
        fail_fmt = "expected {!r}, got {!r}"
        fail_msg = fail_fmt.format(expected, got)
        fail_msg += ' ({})'.format(failure)
        return fail_msg
    else:
        return None

class FloatLike:
    def __init__(self, value):
        self.value = value

    def __float__(self):
        return self.value

class IntSubclass(int):
    pass


class MyIndexable(object):
    def __init__(self, value):
        self.value = value

    def __index__(self):
        return self.value

class BadDescr:
    def __get__(self, obj, objtype=None):
        raise ValueError

class MathTests(unittest.TestCase):

    def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
        
        failure = result_check(expected, got, ulp_tol, abs_tol)
        if failure is not None:
            self.fail("{}: {}".format(name, failure))

    def testConstants(self):
        
        self.ftest('pi', math.pi, 3.141592653589793238462643)
        self.ftest('e', math.e, 2.718281828459045235360287)
        self.assertEqual(math.tau, 2*math.pi)

    def testAcos(self):
        self.assertRaises(TypeError, math.acos)
        self.ftest('acos(-1)', math.acos(-1), math.pi)
        self.ftest('acos(0)', math.acos(0), math.pi/2)
        self.ftest('acos(1)', math.acos(1), 0)
        self.assertRaises(ValueError, math.acos, INF)
        self.assertRaises(ValueError, math.acos, NINF)
        self.assertRaises(ValueError, math.acos, 1 + eps)
        self.assertRaises(ValueError, math.acos, -1 - eps)
        self.assertTrue(math.isnan(math.acos(NAN)))

    def testAcosh(self):
        self.assertRaises(TypeError, math.acosh)
        self.ftest('acosh(1)', math.acosh(1), 0)
        self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
        self.assertRaises(ValueError, math.acosh, 0)
        self.assertRaises(ValueError, math.acosh, -1)
        self.assertEqual(math.acosh(INF), INF)
        self.assertRaises(ValueError, math.acosh, NINF)
        self.assertTrue(math.isnan(math.acosh(NAN)))

    def testAsin(self):
        self.assertRaises(TypeError, math.asin)
        self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
        self.ftest('asin(0)', math.asin(0), 0)
        self.ftest('asin(1)', math.asin(1), math.pi/2)
        self.assertRaises(ValueError, math.asin, INF)
        self.assertRaises(ValueError, math.asin, NINF)
        self.assertRaises(ValueError, math.asin, 1 + eps)
        self.assertRaises(ValueError, math.asin, -1 - eps)
        self.assertTrue(math.isnan(math.asin(NAN)))

    def testAsinh(self):
        self.assertRaises(TypeError, math.asinh)
        self.ftest('asinh(0)', math.asinh(0), 0)
        self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
        self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
        self.assertEqual(math.asinh(INF), INF)
        self.assertEqual(math.asinh(NINF), NINF)
        self.assertTrue(math.isnan(math.asinh(NAN)))

    def testAtan(self):
        self.assertRaises(TypeError, math.atan)
        self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
        self.ftest('atan(0)', math.atan(0), 0)
        self.ftest('atan(1)', math.atan(1), math.pi/4)
        self.ftest('atan(inf)', math.atan(INF), math.pi/2)
        self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
        self.assertTrue(math.isnan(math.atan(NAN)))

    def testAtanh(self):
        self.assertRaises(TypeError, math.atan)
        self.ftest('atanh(0)', math.atanh(0), 0)
        self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
        self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
        self.assertRaises(ValueError, math.atanh, 1)
        self.assertRaises(ValueError, math.atanh, -1)
        self.assertRaises(ValueError, math.atanh, INF)
        self.assertRaises(ValueError, math.atanh, NINF)
        self.assertTrue(math.isnan(math.atanh(NAN)))

    def testAtan2(self):
        self.assertRaises(TypeError, math.atan2)
        self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
        self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
        self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
        self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
        self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
        self.ftest('atan2(1, -1)', math.atan2(1, -1), 3*math.pi/4)

        
        self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
        self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
        self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
        self.assertEqual(math.atan2(0., 0.), 0.)
        self.assertEqual(math.atan2(0., 2.3), 0.)
        self.assertEqual(math.atan2(0., INF), 0.)
        self.assertTrue(math.isnan(math.atan2(0., NAN)))
        
        self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
        self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
        self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
        self.assertEqual(math.atan2(-0., 0.), -0.)
        self.assertEqual(math.atan2(-0., 2.3), -0.)
        self.assertEqual(math.atan2(-0., INF), -0.)
        self.assertTrue(math.isnan(math.atan2(-0., NAN)))
        
        self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
        self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
        self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
        self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
        self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
        self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
        self.assertTrue(math.isnan(math.atan2(INF, NAN)))
        
        self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
        self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
        self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
        self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
        self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
        self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
        self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
        
        self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
        self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
        self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
        self.assertEqual(math.atan2(2.3, INF), 0.)
        self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
        
        self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
        self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
        self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
        self.assertEqual(math.atan2(-2.3, INF), -0.)
        self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
        
        self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
        self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
        self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
        self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
        self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
        self.assertTrue(math.isnan(math.atan2(NAN, INF)))
        self.assertTrue(math.isnan(math.atan2(NAN, NAN)))

    def testCbrt(self):
        self.assertRaises(TypeError, math.cbrt)
        self.ftest('cbrt(0)', math.cbrt(0), 0)
        self.ftest('cbrt(1)', math.cbrt(1), 1)
        self.ftest('cbrt(8)', math.cbrt(8), 2)
        self.ftest('cbrt(0.0)', math.cbrt(0.0), 0.0)
        self.ftest('cbrt(-0.0)', math.cbrt(-0.0), -0.0)
        self.ftest('cbrt(1.2)', math.cbrt(1.2), 1.062658569182611)
        self.ftest('cbrt(-2.6)', math.cbrt(-2.6), -1.375068867074141)
        self.ftest('cbrt(27)', math.cbrt(27), 3)
        self.ftest('cbrt(-1)', math.cbrt(-1), -1)
        self.ftest('cbrt(-27)', math.cbrt(-27), -3)
        self.assertEqual(math.cbrt(INF), INF)
        self.assertEqual(math.cbrt(NINF), NINF)
        self.assertTrue(math.isnan(math.cbrt(NAN)))

    def testCeil(self):
        self.assertRaises(TypeError, math.ceil)
        self.assertEqual(int, type(math.ceil(0.5)))
        self.assertEqual(math.ceil(0.5), 1)
        self.assertEqual(math.ceil(1.0), 1)
        self.assertEqual(math.ceil(1.5), 2)
        self.assertEqual(math.ceil(-0.5), 0)
        self.assertEqual(math.ceil(-1.0), -1)
        self.assertEqual(math.ceil(-1.5), -1)
        self.assertEqual(math.ceil(0.0), 0)
        self.assertEqual(math.ceil(-0.0), 0)
        
        
        

        class TestCeil:
            def __ceil__(self):
                return 42
        class FloatCeil(float):
            def __ceil__(self):
                return 42
        class TestNoCeil:
            pass
        class TestBadCeil:
            __ceil__ = BadDescr()
        self.assertEqual(math.ceil(TestCeil()), 42)
        self.assertEqual(math.ceil(FloatCeil()), 42)
        self.assertEqual(math.ceil(FloatLike(42.5)), 43)
        self.assertRaises(TypeError, math.ceil, TestNoCeil())
        self.assertRaises(ValueError, math.ceil, TestBadCeil())

        t = TestNoCeil()
        t.__ceil__ = lambda *args: args
        self.assertRaises(TypeError, math.ceil, t)
        self.assertRaises(TypeError, math.ceil, t, 0)

        self.assertEqual(math.ceil(FloatLike(+1.0)), +1.0)
        self.assertEqual(math.ceil(FloatLike(-1.0)), -1.0)

    @requires_IEEE_754
    def testCopysign(self):
        self.assertEqual(math.copysign(1, 42), 1.0)
        self.assertEqual(math.copysign(0., 42), 0.0)
        self.assertEqual(math.copysign(1., -42), -1.0)
        self.assertEqual(math.copysign(3, 0.), 3.0)
        self.assertEqual(math.copysign(4., -0.), -4.0)

        self.assertRaises(TypeError, math.copysign)
        
        self.assertEqual(math.copysign(1., 0.), 1.)
        self.assertEqual(math.copysign(1., -0.), -1.)
        self.assertEqual(math.copysign(INF, 0.), INF)
        self.assertEqual(math.copysign(INF, -0.), NINF)
        self.assertEqual(math.copysign(NINF, 0.), INF)
        self.assertEqual(math.copysign(NINF, -0.), NINF)
        
        self.assertEqual(math.copysign(1., INF), 1.)
        self.assertEqual(math.copysign(1., NINF), -1.)
        self.assertEqual(math.copysign(INF, INF), INF)
        self.assertEqual(math.copysign(INF, NINF), NINF)
        self.assertEqual(math.copysign(NINF, INF), INF)
        self.assertEqual(math.copysign(NINF, NINF), NINF)
        self.assertTrue(math.isnan(math.copysign(NAN, 1.)))
        self.assertTrue(math.isnan(math.copysign(NAN, INF)))
        self.assertTrue(math.isnan(math.copysign(NAN, NINF)))
        self.assertTrue(math.isnan(math.copysign(NAN, NAN)))
        
        
        
        self.assertTrue(math.isinf(math.copysign(INF, NAN)))
        
        self.assertEqual(abs(math.copysign(2., NAN)), 2.)

    def testCos(self):
        self.assertRaises(TypeError, math.cos)
        self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0, abs_tol=math.ulp(1))
        self.ftest('cos(0)', math.cos(0), 1)
        self.ftest('cos(pi/2)', math.cos(math.pi/2), 0, abs_tol=math.ulp(1))
        self.ftest('cos(pi)', math.cos(math.pi), -1)
        try:
            self.assertTrue(math.isnan(math.cos(INF)))
            self.assertTrue(math.isnan(math.cos(NINF)))
        except ValueError:
            self.assertRaises(ValueError, math.cos, INF)
            self.assertRaises(ValueError, math.cos, NINF)
        self.assertTrue(math.isnan(math.cos(NAN)))

    @unittest.skipIf(sys.platform == 'win32' and platform.machine() in ('ARM', 'ARM64'),
                    "Windows UCRT is off by 2 ULP this test requires accuracy within 1 ULP")
    def testCosh(self):
        self.assertRaises(TypeError, math.cosh)
        self.ftest('cosh(0)', math.cosh(0), 1)
        self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) 
        self.assertEqual(math.cosh(INF), INF)
        self.assertEqual(math.cosh(NINF), INF)
        self.assertTrue(math.isnan(math.cosh(NAN)))

    def testDegrees(self):
        self.assertRaises(TypeError, math.degrees)
        self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
        self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
        self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
        self.ftest('degrees(0)', math.degrees(0), 0)

    def testExp(self):
        self.assertRaises(TypeError, math.exp)
        self.ftest('exp(-1)', math.exp(-1), 1/math.e)
        self.ftest('exp(0)', math.exp(0), 1)
        self.ftest('exp(1)', math.exp(1), math.e)
        self.assertEqual(math.exp(INF), INF)
        self.assertEqual(math.exp(NINF), 0.)
        self.assertTrue(math.isnan(math.exp(NAN)))
        self.assertRaises(OverflowError, math.exp, 1000000)

    def testExp2(self):
        self.assertRaises(TypeError, math.exp2)
        self.ftest('exp2(-1)', math.exp2(-1), 0.5)
        self.ftest('exp2(0)', math.exp2(0), 1)
        self.ftest('exp2(1)', math.exp2(1), 2)
        self.ftest('exp2(2.3)', math.exp2(2.3), 4.924577653379665)
        self.assertEqual(math.exp2(INF), INF)
        self.assertEqual(math.exp2(NINF), 0.)
        self.assertTrue(math.isnan(math.exp2(NAN)))
        self.assertRaises(OverflowError, math.exp2, 1000000)

    def testFabs(self):
        self.assertRaises(TypeError, math.fabs)
        self.ftest('fabs(-1)', math.fabs(-1), 1)
        self.ftest('fabs(0)', math.fabs(0), 0)
        self.ftest('fabs(1)', math.fabs(1), 1)

    def testFactorial(self):
        self.assertEqual(math.factorial(0), 1)
        total = 1
        for i in range(1, 1000):
            total *= i
            self.assertEqual(math.factorial(i), total)
            self.assertEqual(math.factorial(i), py_factorial(i))
        self.assertRaises(ValueError, math.factorial, -1)
        self.assertRaises(ValueError, math.factorial, -10**100)

    def testFactorialNonIntegers(self):
        self.assertRaises(TypeError, math.factorial, 5.0)
        self.assertRaises(TypeError, math.factorial, 5.2)
        self.assertRaises(TypeError, math.factorial, -1.0)
        self.assertRaises(TypeError, math.factorial, -1e100)
        self.assertRaises(TypeError, math.factorial, decimal.Decimal('5'))
        self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2'))
        self.assertRaises(TypeError, math.factorial, "5")

    
    @support.cpython_only
    def testFactorialHugeInputs(self):
        
        
        self.assertRaises(OverflowError, math.factorial, 10**100)
        self.assertRaises(TypeError, math.factorial, 1e100)

    def testFloor(self):
        self.assertRaises(TypeError, math.floor)
        self.assertEqual(int, type(math.floor(0.5)))
        self.assertEqual(math.floor(0.5), 0)
        self.assertEqual(math.floor(1.0), 1)
        self.assertEqual(math.floor(1.5), 1)
        self.assertEqual(math.floor(-0.5), -1)
        self.assertEqual(math.floor(-1.0), -1)
        self.assertEqual(math.floor(-1.5), -2)
        
        
        

        class TestFloor:
            def __floor__(self):
                return 42
        class FloatFloor(float):
            def __floor__(self):
                return 42
        class TestNoFloor:
            pass
        class TestBadFloor:
            __floor__ = BadDescr()
        self.assertEqual(math.floor(TestFloor()), 42)
        self.assertEqual(math.floor(FloatFloor()), 42)
        self.assertEqual(math.floor(FloatLike(41.9)), 41)
        self.assertRaises(TypeError, math.floor, TestNoFloor())
        self.assertRaises(ValueError, math.floor, TestBadFloor())

        t = TestNoFloor()
        t.__floor__ = lambda *args: args
        self.assertRaises(TypeError, math.floor, t)
        self.assertRaises(TypeError, math.floor, t, 0)

        self.assertEqual(math.floor(FloatLike(+1.0)), +1.0)
        self.assertEqual(math.floor(FloatLike(-1.0)), -1.0)

    def testFmod(self):
        self.assertRaises(TypeError, math.fmod)
        self.ftest('fmod(10, 1)', math.fmod(10, 1), 0.0)
        self.ftest('fmod(10, 0.5)', math.fmod(10, 0.5), 0.0)
        self.ftest('fmod(10, 1.5)', math.fmod(10, 1.5), 1.0)
        self.ftest('fmod(-10, 1)', math.fmod(-10, 1), -0.0)
        self.ftest('fmod(-10, 0.5)', math.fmod(-10, 0.5), -0.0)
        self.ftest('fmod(-10, 1.5)', math.fmod(-10, 1.5), -1.0)
        self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
        self.assertTrue(math.isnan(math.fmod(1., NAN)))
        self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
        self.assertRaises(ValueError, math.fmod, 1., 0.)
        self.assertRaises(ValueError, math.fmod, INF, 1.)
        self.assertRaises(ValueError, math.fmod, NINF, 1.)
        self.assertRaises(ValueError, math.fmod, INF, 0.)
        self.assertEqual(math.fmod(3.0, INF), 3.0)
        self.assertEqual(math.fmod(-3.0, INF), -3.0)
        self.assertEqual(math.fmod(3.0, NINF), 3.0)
        self.assertEqual(math.fmod(-3.0, NINF), -3.0)
        self.assertEqual(math.fmod(0.0, 3.0), 0.0)
        self.assertEqual(math.fmod(0.0, NINF), 0.0)
        self.assertRaises(ValueError, math.fmod, INF, INF)

    def testFrexp(self):
        self.assertRaises(TypeError, math.frexp)

        def testfrexp(name, result, expected):
            (mant, exp), (emant, eexp) = result, expected
            if abs(mant-emant) > eps or exp != eexp:
                self.fail('%s returned %r, expected %r'%\
                          (name, result, expected))

        testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
        testfrexp('frexp(0)', math.frexp(0), (0, 0))
        testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
        testfrexp('frexp(2)', math.frexp(2), (0.5, 2))

        self.assertEqual(math.frexp(INF)[0], INF)
        self.assertEqual(math.frexp(NINF)[0], NINF)
        self.assertTrue(math.isnan(math.frexp(NAN)[0]))

    @requires_IEEE_754
    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
                         "fsum is not exact on machines with double rounding")
    def testFsum(self):
        
        
        
        
        
        
        

        
        
        
        from sys import float_info
        mant_dig = float_info.mant_dig
        etiny = float_info.min_exp - mant_dig

        def msum(iterable):
            
            tmant, texp = 0, 0
            for x in iterable:
                mant, exp = math.frexp(x)
                mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
                if texp > exp:
                    tmant <<= texp-exp
                    texp = exp
                else:
                    mant <<= exp-texp
                tmant += mant
            
            
            
            
            tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
            if tail > 0:
                h = 1 << (tail-1)
                tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
                texp += tail
            return math.ldexp(tmant, texp)

        test_values = [
            ([], 0.0),
            ([0.0], 0.0),
            ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
            ([1e100, 1.0, -1e100, 1e-100, 1e50, -1, -1e50], 1e-100),
            ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
            ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
            ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
            ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
            ([1./n for n in range(1, 1001)],
             float.fromhex('0x1.df11f45f4e61ap+2')),
            ([(-1.)**n/n for n in range(1, 1001)],
             float.fromhex('-0x1.62a2af1bd3624p-1')),
            ([1e16, 1., 1e-16], 10000000000000002.0),
            ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
            
            ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
             [-2.**1022],
             float.fromhex('0x1.5555555555555p+970')),
            ]

        
        terms = [1.7**i for i in range(1001)]
        test_values.append((
            [terms[i+1] - terms[i] for i in range(1000)] + [-terms[1000]],
            -terms[0]
        ))

        for i, (vals, expected) in enumerate(test_values):
            try:
                actual = math.fsum(vals)
            except OverflowError:
                self.fail("test %d failed: got OverflowError, expected %r "
                          "for math.fsum(%.100r)" % (i, expected, vals))
            except ValueError:
                self.fail("test %d failed: got ValueError, expected %r "
                          "for math.fsum(%.100r)" % (i, expected, vals))
            self.assertEqual(actual, expected)

        from random import random, gauss, shuffle
        for j in range(1000):
            vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
            s = 0
            for i in range(200):
                v = gauss(0, random()) ** 7 - s
                s += v
                vals.append(v)
            shuffle(vals)

            s = msum(vals)
            self.assertEqual(msum(vals), math.fsum(vals))

        self.assertEqual(math.fsum([1.0, math.inf]), math.inf)
        self.assertTrue(math.isnan(math.fsum([math.nan, 1.0])))
        self.assertEqual(math.fsum([1e100, FloatLike(1.0), -1e100, 1e-100,
                                    1e50, FloatLike(-1.0), -1e50]), 1e-100)
        self.assertRaises(OverflowError, math.fsum, [1e+308, 1e+308])
        self.assertRaises(ValueError, math.fsum, [math.inf, -math.inf])
        self.assertRaises(TypeError, math.fsum, ['spam'])
        self.assertRaises(TypeError, math.fsum, 1)
        self.assertRaises(OverflowError, math.fsum, [10**1000])

        def bad_iter():
            yield 1.0
            raise ZeroDivisionError

        self.assertRaises(ZeroDivisionError, math.fsum, bad_iter())

    def testGcd(self):
        gcd = math.gcd
        self.assertEqual(gcd(0, 0), 0)
        self.assertEqual(gcd(1, 0), 1)
        self.assertEqual(gcd(-1, 0), 1)
        self.assertEqual(gcd(0, 1), 1)
        self.assertEqual(gcd(0, -1), 1)
        self.assertEqual(gcd(7, 1), 1)
        self.assertEqual(gcd(7, -1), 1)
        self.assertEqual(gcd(-23, 15), 1)
        self.assertEqual(gcd(120, 84), 12)
        self.assertEqual(gcd(84, -120), 12)
        self.assertEqual(gcd(1216342683557601535506311712,
                             436522681849110124616458784), 32)

        x = 434610456570399902378880679233098819019853229470286994367836600566
        y = 1064502245825115327754847244914921553977
        for c in (652560,
                  576559230871654959816130551884856912003141446781646602790216406874):
            a = x * c
            b = y * c
            self.assertEqual(gcd(a, b), c)
            self.assertEqual(gcd(b, a), c)
            self.assertEqual(gcd(-a, b), c)
            self.assertEqual(gcd(b, -a), c)
            self.assertEqual(gcd(a, -b), c)
            self.assertEqual(gcd(-b, a), c)
            self.assertEqual(gcd(-a, -b), c)
            self.assertEqual(gcd(-b, -a), c)

        self.assertEqual(gcd(), 0)
        self.assertEqual(gcd(120), 120)
        self.assertEqual(gcd(-120), 120)
        self.assertEqual(gcd(120, 84, 102), 6)
        self.assertEqual(gcd(120, 1, 84), 1)

        self.assertRaises(TypeError, gcd, 120.0)
        self.assertRaises(TypeError, gcd, 120.0, 84)
        self.assertRaises(TypeError, gcd, 120, 84.0)
        self.assertRaises(TypeError, gcd, 120, 1, 84.0)
        self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12)

    def testHypot(self):
        from decimal import Decimal
        from fractions import Fraction

        hypot = math.hypot

        
        
        args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1)
        for i in range(len(args)+1):
            self.assertAlmostEqual(
                hypot(*args[:i]),
                math.sqrt(sum(s**2 for s in args[:i]))
            )

        
        self.assertEqual(hypot(12.0, 5.0), 13.0)
        self.assertEqual(hypot(12, 5), 13)
        self.assertEqual(hypot(1, -1), math.sqrt(2))
        self.assertEqual(hypot(1, FloatLike(-1.)), math.sqrt(2))
        self.assertEqual(hypot(Decimal(12), Decimal(5)), 13)
        self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32))
        self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3))

        
        self.assertEqual(hypot(0.0, 0.0), 0.0)     
        self.assertEqual(hypot(-10.5), 10.5)       
        self.assertEqual(hypot(), 0.0)             
        self.assertEqual(1.0,
            math.copysign(1.0, hypot(-0.0))        
        )
        self.assertEqual(                          
            hypot(1.5, 1.5, 0.5),
            hypot(1.5, 0.5, 1.5),
        )

        
        with self.assertRaises(TypeError):         
            hypot(x=1)
        with self.assertRaises(TypeError):         
            hypot(1.1, 'string', 2.2)
        int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
        with self.assertRaises((ValueError, OverflowError)):
            hypot(1, int_too_big_for_float)

        
        self.assertEqual(hypot(INF), INF)
        self.assertEqual(hypot(0, INF), INF)
        self.assertEqual(hypot(10, INF), INF)
        self.assertEqual(hypot(-10, INF), INF)
        self.assertEqual(hypot(NAN, INF), INF)
        self.assertEqual(hypot(INF, NAN), INF)
        self.assertEqual(hypot(NINF, NAN), INF)
        self.assertEqual(hypot(NAN, NINF), INF)
        self.assertEqual(hypot(-INF, INF), INF)
        self.assertEqual(hypot(-INF, -INF), INF)
        self.assertEqual(hypot(10, -INF), INF)

        
        self.assertTrue(math.isnan(hypot(NAN)))
        self.assertTrue(math.isnan(hypot(0, NAN)))
        self.assertTrue(math.isnan(hypot(NAN, 10)))
        self.assertTrue(math.isnan(hypot(10, NAN)))
        self.assertTrue(math.isnan(hypot(NAN, NAN)))
        self.assertTrue(math.isnan(hypot(NAN)))

        
        fourthmax = FLOAT_MAX / 4.0
        for n in range(32):
            self.assertTrue(math.isclose(hypot(*([fourthmax]*n)),
                                         fourthmax * math.sqrt(n)))

        
        for exp in range(32):
            scale = FLOAT_MIN / 2.0 ** exp
            self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale)

        self.assertRaises(TypeError, math.hypot, *([1.0]*18), 'spam')

    @requires_IEEE_754
    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
                     "hypot() loses accuracy on machines with double rounding")
    def testHypotAccuracy(self):
        
        
        
        
        
        
        
        
        
        

        hypot = math.hypot
        Decimal = decimal.Decimal
        high_precision = decimal.Context(prec=500)

        for hx, hy in [
            
            ('0x1.10e89518dca48p+29', '0x1.1970f7565b7efp+30'),
            ('0x1.10106eb4b44a2p+29', '0x1.ef0596cdc97f8p+29'),
            ('0x1.459c058e20bb7p+30', '0x1.993ca009b9178p+29'),
            ('0x1.378371ae67c0cp+30', '0x1.fbe6619854b4cp+29'),
            ('0x1.f4cd0574fb97ap+29', '0x1.50fe31669340ep+30'),
            ('0x1.494b2cdd3d446p+29', '0x1.212a5367b4c7cp+29'),
            ('0x1.f84e649f1e46dp+29', '0x1.1fa56bef8eec4p+30'),
            ('0x1.2e817edd3d6fap+30', '0x1.eb0814f1e9602p+29'),
            ('0x1.0d3a6e3d04245p+29', '0x1.32a62fea52352p+30'),
            ('0x1.888e19611bfc5p+29', '0x1.52b8e70b24353p+29'),

            
            ('0x1.538816d48a13fp+29', '0x1.7967c5ca43e16p+29'),
            ('0x1.57b47b7234530p+29', '0x1.74e2c7040e772p+29'),
            ('0x1.821b685e9b168p+30', '0x1.677dc1c1e3dc6p+29'),
            ('0x1.9e8247f67097bp+29', '0x1.24bd2dc4f4baep+29'),
            ('0x1.b73b59e0cb5f9p+29', '0x1.da899ab784a97p+28'),
            ('0x1.94a8d2842a7cfp+30', '0x1.326a51d4d8d8ap+30'),
            ('0x1.e930b9cd99035p+29', '0x1.5a1030e18dff9p+30'),
            ('0x1.1592bbb0e4690p+29', '0x1.a9c337b33fb9ap+29'),
            ('0x1.1243a50751fd4p+29', '0x1.a5a10175622d9p+29'),
            ('0x1.57a8596e74722p+30', '0x1.42d1af9d04da9p+30'),

            
            ('0x1.ee7dbd9565899p+29', '0x1.7ab4d6fc6e4b4p+29'),
            ('0x1.5c6bfbec5c4dcp+30', '0x1.02511184b4970p+30'),
            ('0x1.59dcebba995cap+30', '0x1.50ca7e7c38854p+29'),
            ('0x1.768cdd94cf5aap+29', '0x1.9cfdc5571d38ep+29'),
            ('0x1.dcf137d60262ep+29', '0x1.1101621990b3ep+30'),
            ('0x1.3a2d006e288b0p+30', '0x1.e9a240914326cp+29'),
            ('0x1.62a32f7f53c61p+29', '0x1.47eb6cd72684fp+29'),
            ('0x1.d3bcb60748ef2p+29', '0x1.3f13c4056312cp+30'),
            ('0x1.282bdb82f17f3p+30', '0x1.640ba4c4eed3ap+30'),
            ('0x1.89d8c423ea0c6p+29', '0x1.d35dcfe902bc3p+29'),
        ]:
            x = float.fromhex(hx)
            y = float.fromhex(hy)
            with self.subTest(hx=hx, hy=hy, x=x, y=y):
                with decimal.localcontext(high_precision):
                    z = float((Decimal(x)**2 + Decimal(y)**2).sqrt())
                self.assertEqual(hypot(x, y), z)

    def testDist(self):
        from decimal import Decimal as D
        from fractions import Fraction as F

        dist = math.dist
        sqrt = math.sqrt

        
        self.assertEqual(dist((1.0, 2.0, 3.0), (4.0, 2.0, -1.0)), 5.0)
        self.assertEqual(dist((1, 2, 3), (4, 2, -1)), 5.0)

        
        
        for i in range(9):
            for j in range(5):
                p = tuple(random.uniform(-5, 5) for k in range(i))
                q = tuple(random.uniform(-5, 5) for k in range(i))
                self.assertAlmostEqual(
                    dist(p, q),
                    sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
                )

        
        self.assertEqual(dist([1.0, 2.0, 3.0], [4.0, 2.0, -1.0]), 5.0)
        self.assertEqual(dist(iter([1.0, 2.0, 3.0]), iter([4.0, 2.0, -1.0])), 5.0)

        
        self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0)
        self.assertEqual(dist((14, 1), (2, -4)), 13)
        self.assertEqual(dist((FloatLike(14.), 1), (2, -4)), 13)
        self.assertEqual(dist((11, 1), (FloatLike(-1.), -4)), 13)
        self.assertEqual(dist((14, FloatLike(-1.)), (2, -6)), 13)
        self.assertEqual(dist((14, -1), (2, -6)), 13)
        self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13))
        self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))),
                         F(13, 32))
        self.assertEqual(dist((True, True, False, True, False),
                              (True, False, True, True, False)),
                         sqrt(2.0))

        
        self.assertEqual(dist((13.25, 12.5, -3.25),
                              (13.25, 12.5, -3.25)),
                         0.0)                      
        self.assertEqual(dist((), ()), 0.0)        
        self.assertEqual(1.0,                      
            math.copysign(1.0, dist((-0.0,), (0.0,)))
        )
        self.assertEqual(1.0,                      
            math.copysign(1.0, dist((0.0,), (-0.0,)))
        )
        self.assertEqual(                          
            dist((1.5, 1.5, 0.5), (0, 0, 0)),
            dist((1.5, 0.5, 1.5), (0, 0, 0))
        )

        
        class T(tuple):
            pass
        self.assertEqual(dist(T((1, 2, 3)), ((4, 2, -1))), 5.0)

        
        with self.assertRaises(TypeError):         
            dist(p=(1, 2, 3), q=(4, 5, 6))
        with self.assertRaises(TypeError):         
            dist((1, 2, 3))
        with self.assertRaises(TypeError):         
            dist((1, 2, 3), (4, 5, 6), (7, 8, 9))
        with self.assertRaises(TypeError):         
            dist(1, 2)
        with self.assertRaises(TypeError):         
            dist((1.1, 'string', 2.2), (1, 2, 3))
        with self.assertRaises(ValueError):        
            dist((1, 2, 3, 4), (5, 6, 7))
        with self.assertRaises(ValueError):        
            dist((1, 2, 3), (4, 5, 6, 7))
        with self.assertRaises(TypeError):
            dist((1,)*17 + ("spam",), (1,)*18)
        with self.assertRaises(TypeError):         
            dist("abc", "xyz")
        int_too_big_for_float = 10 ** (sys.float_info.max_10_exp + 5)
        with self.assertRaises((ValueError, OverflowError)):
            dist((1, int_too_big_for_float), (2, 3))
        with self.assertRaises((ValueError, OverflowError)):
            dist((2, 3), (1, int_too_big_for_float))
        with self.assertRaises(TypeError):
            dist((1,), 2)
        with self.assertRaises(TypeError):
            dist([1], 2)

        class BadFloat:
            __float__ = BadDescr()

        with self.assertRaises(ValueError):
            dist([1], [BadFloat()])

        
        for i in range(20):
            p, q = random.random(), random.random()
            self.assertEqual(dist((p,), (q,)), abs(p - q))

        
        values = [NINF, -10.5, -0.0, 0.0, 10.5, INF, NAN]
        for p in itertools.product(values, repeat=3):
            for q in itertools.product(values, repeat=3):
                diffs = [px - qx for px, qx in zip(p, q)]
                if any(map(math.isinf, diffs)):
                    
                    self.assertEqual(dist(p, q), INF)
                elif any(map(math.isnan, diffs)):
                    
                    self.assertTrue(math.isnan(dist(p, q)))

        
        fourthmax = FLOAT_MAX / 4.0
        for n in range(32):
            p = (fourthmax,) * n
            q = (0.0,) * n
            self.assertTrue(math.isclose(dist(p, q), fourthmax * math.sqrt(n)))
            self.assertTrue(math.isclose(dist(q, p), fourthmax * math.sqrt(n)))

        
        for exp in range(32):
            scale = FLOAT_MIN / 2.0 ** exp
            p = (4*scale, 3*scale)
            q = (0.0, 0.0)
            self.assertEqual(math.dist(p, q), 5*scale)
            self.assertEqual(math.dist(q, p), 5*scale)

    def test_math_dist_leak(self):
        
        with self.assertRaises(ValueError):
            math.dist([1, 2], [3, 4, 5])

    def testIsqrt(self):
        
        test_values = (
            list(range(1000))
            + list(range(10**6 - 1000, 10**6 + 1000))
            + [2**e + i for e in range(60, 200) for i in range(-40, 40)]
            + [3**9999, 10**5001]
        )

        for value in test_values:
            with self.subTest(value=value):
                s = math.isqrt(value)
                self.assertIs(type(s), int)
                self.assertLessEqual(s*s, value)
                self.assertLess(value, (s+1)*(s+1))

        
        with self.assertRaises(ValueError):
            math.isqrt(-1)

        
        s = math.isqrt(True)
        self.assertIs(type(s), int)
        self.assertEqual(s, 1)

        s = math.isqrt(False)
        self.assertIs(type(s), int)
        self.assertEqual(s, 0)

        class IntegerLike(object):
            def __init__(self, value):
                self.value = value

            def __index__(self):
                return self.value

        s = math.isqrt(IntegerLike(1729))
        self.assertIs(type(s), int)
        self.assertEqual(s, 41)

        with self.assertRaises(ValueError):
            math.isqrt(IntegerLike(-3))

        
        bad_values = [
            3.5, "a string", decimal.Decimal("3.5"), 3.5j,
            100.0, -4.0,
        ]
        for value in bad_values:
            with self.subTest(value=value):
                with self.assertRaises(TypeError):
                    math.isqrt(value)

    def test_lcm(self):
        lcm = math.lcm
        self.assertEqual(lcm(0, 0), 0)
        self.assertEqual(lcm(1, 0), 0)
        self.assertEqual(lcm(-1, 0), 0)
        self.assertEqual(lcm(0, 1), 0)
        self.assertEqual(lcm(0, -1), 0)
        self.assertEqual(lcm(7, 1), 7)
        self.assertEqual(lcm(7, -1), 7)
        self.assertEqual(lcm(-23, 15), 345)
        self.assertEqual(lcm(120, 84), 840)
        self.assertEqual(lcm(84, -120), 840)
        self.assertEqual(lcm(1216342683557601535506311712,
                             436522681849110124616458784),
                             16592536571065866494401400422922201534178938447014944)

        x = 43461045657039990237
        y = 10645022458251153277
        for c in (652560,
                  57655923087165495981):
            a = x * c
            b = y * c
            d = x * y * c
            self.assertEqual(lcm(a, b), d)
            self.assertEqual(lcm(b, a), d)
            self.assertEqual(lcm(-a, b), d)
            self.assertEqual(lcm(b, -a), d)
            self.assertEqual(lcm(a, -b), d)
            self.assertEqual(lcm(-b, a), d)
            self.assertEqual(lcm(-a, -b), d)
            self.assertEqual(lcm(-b, -a), d)

        self.assertEqual(lcm(), 1)
        self.assertEqual(lcm(120), 120)
        self.assertEqual(lcm(-120), 120)
        self.assertEqual(lcm(120, 84, 102), 14280)
        self.assertEqual(lcm(120, 0, 84), 0)

        self.assertRaises(TypeError, lcm, 120.0)
        self.assertRaises(TypeError, lcm, 120.0, 84)
        self.assertRaises(TypeError, lcm, 120, 84.0)
        self.assertRaises(TypeError, lcm, 120, 0, 84.0)
        self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840)

    def testLdexp(self):
        self.assertRaises(TypeError, math.ldexp)
        self.assertRaises(TypeError, math.ldexp, 2.0, 1.1)
        self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
        self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
        self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
        self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
        self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
        self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
        self.assertEqual(math.ldexp(1., -1000000), 0.)
        self.assertEqual(math.ldexp(-1., -1000000), -0.)
        self.assertEqual(math.ldexp(INF, 30), INF)
        self.assertEqual(math.ldexp(NINF, -213), NINF)
        self.assertTrue(math.isnan(math.ldexp(NAN, 0)))

        
        for n in [10**5, 10**10, 10**20, 10**40]:
            self.assertEqual(math.ldexp(INF, -n), INF)
            self.assertEqual(math.ldexp(NINF, -n), NINF)
            self.assertEqual(math.ldexp(1., -n), 0.)
            self.assertEqual(math.ldexp(-1., -n), -0.)
            self.assertEqual(math.ldexp(0., -n), 0.)
            self.assertEqual(math.ldexp(-0., -n), -0.)
            self.assertTrue(math.isnan(math.ldexp(NAN, -n)))

            self.assertRaises(OverflowError, math.ldexp, 1., n)
            self.assertRaises(OverflowError, math.ldexp, -1., n)
            self.assertEqual(math.ldexp(0., n), 0.)
            self.assertEqual(math.ldexp(-0., n), -0.)
            self.assertEqual(math.ldexp(INF, n), INF)
            self.assertEqual(math.ldexp(NINF, n), NINF)
            self.assertTrue(math.isnan(math.ldexp(NAN, n)))

    def testLog(self):
        self.assertRaises(TypeError, math.log)
        self.assertRaises(TypeError, math.log, 1, 2, 3)
        self.ftest('log(1/e)', math.log(1/math.e), -1)
        self.ftest('log(1)', math.log(1), 0)
        self.ftest('log(e)', math.log(math.e), 1)
        self.ftest('log(32,2)', math.log(32,2), 5)
        self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
        self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
        self.ftest('log(10**1000)', math.log(10**1000),
                   2302.5850929940457)
        self.assertRaises(ValueError, math.log, -1.5)
        self.assertRaises(ValueError, math.log, -10**1000)
        self.assertRaises(ValueError, math.log, 10, -10)
        self.assertRaises(ValueError, math.log, NINF)
        self.assertEqual(math.log(INF), INF)
        self.assertTrue(math.isnan(math.log(NAN)))

    def testLog1p(self):
        self.assertRaises(TypeError, math.log1p)
        for n in [2, 2**90, 2**300]:
            self.assertAlmostEqual(math.log1p(n), math.log1p(float(n)))
        self.assertRaises(ValueError, math.log1p, -1)
        self.assertEqual(math.log1p(INF), INF)

    @requires_IEEE_754
    def testLog2(self):
        self.assertRaises(TypeError, math.log2)

        
        self.assertEqual(math.log2(1), 0.0)
        self.assertEqual(math.log2(2), 1.0)
        self.assertEqual(math.log2(4), 2.0)

        
        self.assertEqual(math.log2(2**1023), 1023.0)
        self.assertEqual(math.log2(2**1024), 1024.0)
        self.assertEqual(math.log2(2**2000), 2000.0)

        self.assertRaises(ValueError, math.log2, -1.5)
        self.assertRaises(ValueError, math.log2, NINF)
        self.assertTrue(math.isnan(math.log2(NAN)))

    @requires_IEEE_754
    
    @support.requires_mac_ver(10, 5)
    def testLog2Exact(self):
        
        actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)]
        expected = [float(n) for n in range(-1074, 1024)]
        self.assertEqual(actual, expected)

    def testLog10(self):
        self.assertRaises(TypeError, math.log10)
        self.ftest('log10(0.1)', math.log10(0.1), -1)
        self.ftest('log10(1)', math.log10(1), 0)
        self.ftest('log10(10)', math.log10(10), 1)
        self.ftest('log10(10**1000)', math.log10(10**1000), 1000.0)
        self.assertRaises(ValueError, math.log10, -1.5)
        self.assertRaises(ValueError, math.log10, -10**1000)
        self.assertRaises(ValueError, math.log10, NINF)
        self.assertEqual(math.log(INF), INF)
        self.assertTrue(math.isnan(math.log10(NAN)))

    def testSumProd(self):
        sumprod = math.sumprod
        Decimal = decimal.Decimal
        Fraction = fractions.Fraction

        
        self.assertEqual(sumprod(iter([10, 20, 30]), (1, 2, 3)), 140)
        self.assertEqual(sumprod([1.5, 2.5], [3.5, 4.5]), 16.5)
        self.assertEqual(sumprod([], []), 0)
        self.assertEqual(sumprod([-1], [1.]), -1)
        self.assertEqual(sumprod([1.], [-1]), -1)

        
        for v in [
            (10, 20, 30),
            (1.5, -2.5),
            (Fraction(3, 5), Fraction(4, 5)),
            (Decimal(3.5), Decimal(4.5)),
            (2.5, 10),             
            (2.5, Fraction(3, 5)), 
            (25, Fraction(3, 5)),  
            (25, Decimal(4.5)),    
        ]:
            for p, q in [(v, v), (v, v[::-1])]:
                with self.subTest(p=p, q=q):
                    expected = sum(p_i * q_i for p_i, q_i in zip(p, q, strict=True))
                    actual = sumprod(p, q)
                    self.assertEqual(expected, actual)
                    self.assertEqual(type(expected), type(actual))

        
        self.assertRaises(TypeError, sumprod)               
        self.assertRaises(TypeError, sumprod, [])           
        self.assertRaises(TypeError, sumprod, [], [], [])   
        self.assertRaises(TypeError, sumprod, None, [10])   
        self.assertRaises(TypeError, sumprod, [10], None)   
        self.assertRaises(TypeError, sumprod, ['x'], [1.0])

        
        self.assertRaises(ValueError, sumprod, [10, 20], [30])
        self.assertRaises(ValueError, sumprod, [10], [20, 30])

        
        self.assertEqual(sumprod([10**20], [1]), 10**20)
        self.assertEqual(sumprod([1], [10**20]), 10**20)
        self.assertEqual(sumprod([10**10], [10**10]), 10**20)
        self.assertEqual(sumprod([10**7]*10**5, [10**7]*10**5), 10**19)
        self.assertRaises(OverflowError, sumprod, [10**1000], [1.0])
        self.assertRaises(OverflowError, sumprod, [1.0], [10**1000])

        
        def raise_after(n):
            for i in range(n):
                yield i
            raise RuntimeError
        with self.assertRaises(RuntimeError):
            sumprod(range(10), raise_after(5))
        with self.assertRaises(RuntimeError):
            sumprod(raise_after(5), range(10))

        from test.test_iter import BasicIterClass

        self.assertEqual(sumprod(BasicIterClass(1), [1]), 0)
        self.assertEqual(sumprod([1], BasicIterClass(1)), 0)

        
        class BadMultiply:
            def __mul__(self, other):
                raise RuntimeError
            def __rmul__(self, other):
                raise RuntimeError
        with self.assertRaises(RuntimeError):
            sumprod([10, BadMultiply(), 30], [1, 2, 3])
        with self.assertRaises(RuntimeError):
            sumprod([1, 2, 3], [10, BadMultiply(), 30])

        
        with self.assertRaises(TypeError):
            sumprod(['abc', 3], [5, 10])
        with self.assertRaises(TypeError):
            sumprod([5, 10], ['abc', 3])

        
        self.assertEqual(sumprod([10.1, math.inf], [20.2, 30.3]), math.inf)
        self.assertEqual(sumprod([10.1, math.inf], [math.inf, 30.3]), math.inf)
        self.assertEqual(sumprod([10.1, math.inf], [math.inf, math.inf]), math.inf)
        self.assertEqual(sumprod([10.1, -math.inf], [20.2, 30.3]), -math.inf)
        self.assertTrue(math.isnan(sumprod([10.1, math.inf], [-math.inf, math.inf])))
        self.assertTrue(math.isnan(sumprod([10.1, math.nan], [20.2, 30.3])))
        self.assertTrue(math.isnan(sumprod([10.1, math.inf], [math.nan, 30.3])))
        self.assertTrue(math.isnan(sumprod([10.1, math.inf], [20.3, math.nan])))

        
        args = ((-5, -5, 10), (1.5, 4611686018427387904, 2305843009213693952))
        self.assertEqual(sumprod(*args), 0.0)


    @requires_IEEE_754
    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
                         "sumprod() accuracy not guaranteed on machines with double rounding")
    @support.cpython_only    
    def test_sumprod_accuracy(self):
        sumprod = math.sumprod
        self.assertEqual(sumprod([0.1] * 10, [1]*10), 1.0)
        self.assertEqual(sumprod([0.1] * 20, [True, False] * 10), 1.0)
        self.assertEqual(sumprod([True, False] * 10, [0.1] * 20), 1.0)
        self.assertEqual(sumprod([1.0, 10E100, 1.0, -10E100], [1.0]*4), 2.0)

    @support.requires_resource('cpu')
    def test_sumprod_stress(self):
        sumprod = math.sumprod
        product = itertools.product
        Decimal = decimal.Decimal
        Fraction = fractions.Fraction

        class Int(int):
            def __add__(self, other):
                return Int(int(self) + int(other))
            def __mul__(self, other):
                return Int(int(self) * int(other))
            __radd__ = __add__
            __rmul__ = __mul__
            def __repr__(self):
                return f'Int({int(self)})'

        class Flt(float):
            def __add__(self, other):
                return Int(int(self) + int(other))
            def __mul__(self, other):
                return Int(int(self) * int(other))
            __radd__ = __add__
            __rmul__ = __mul__
            def __repr__(self):
                return f'Flt({int(self)})'

        def baseline_sumprod(p, q):
            
            total = 0
            for p_i, q_i in zip(p, q, strict=True):
                total += p_i * q_i
            return total

        def run(func, *args):
            "Make comparing functions easier. Returns error status, type, and result."
            try:
                result = func(*args)
            except (AssertionError, NameError):
                raise
            except Exception as e:
                return type(e), None, 'None'
            return None, type(result), repr(result)

        pools = [
            (-5, 10, -2**20, 2**31, 2**40, 2**61, 2**62, 2**80, 1.5, Int(7)),
            (5.25, -3.5, 4.75, 11.25, 400.5, 0.046875, 0.25, -1.0, -0.078125),
            (-19.0*2**500, 11*2**1000, -3*2**1500, 17*2*333,
               5.25, -3.25, -3.0*2**(-333),  3, 2**513),
            (3.75, 2.5, -1.5, float('inf'), -float('inf'), float('NaN'), 14,
                9, 3+4j, Flt(13), 0.0),
            (13.25, -4.25, Decimal('10.5'), Decimal('-2.25'), Fraction(13, 8),
                 Fraction(-11, 16), 4.75 + 0.125j, 97, -41, Int(3)),
            (Decimal('6.125'), Decimal('12.375'), Decimal('-2.75'), Decimal(0),
                 Decimal('Inf'), -Decimal('Inf'), Decimal('NaN'), 12, 13.5),
            (-2.0 ** -1000, 11*2**1000, 3, 7, -37*2**32, -2*2**-537, -2*2**-538,
                 2*2**-513),
            (-7 * 2.0 ** -510, 5 * 2.0 ** -520, 17, -19.0, -6.25),
            (11.25, -3.75, -0.625, 23.375, True, False, 7, Int(5)),
        ]

        for pool in pools:
            for size in range(4):
                for args1 in product(pool, repeat=size):
                    for args2 in product(pool, repeat=size):
                        args = (args1, args2)
                        self.assertEqual(
                            run(baseline_sumprod, *args),
                            run(sumprod, *args),
                            args,
                        )

    @requires_IEEE_754
    @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
                         "sumprod() accuracy not guaranteed on machines with double rounding")
    @support.cpython_only    
    @support.requires_resource('cpu')
    def test_sumprod_extended_precision_accuracy(self):
        import operator
        from fractions import Fraction
        from itertools import starmap
        from collections import namedtuple
        from math import log2, exp2, fabs
        from random import choices, uniform, shuffle
        from statistics import median

        DotExample = namedtuple('DotExample', ('x', 'y', 'target_sumprod', 'condition'))

        def DotExact(x, y):
            vec1 = map(Fraction, x)
            vec2 = map(Fraction, y)
            return sum(starmap(operator.mul, zip(vec1, vec2, strict=True)))

        def Condition(x, y):
            return 2.0 * DotExact(map(abs, x), map(abs, y)) / abs(DotExact(x, y))

        def linspace(lo, hi, n):
            width = (hi - lo) / (n - 1)
            return [lo + width * i for i in range(n)]

        def GenDot(n, c):
            

            assert n >= 6
            n2 = n // 2
            x = [0.0] * n
            y = [0.0] * n
            b = log2(c)

            
            e = choices(range(int(b/2)), k=n2)
            e[0] = int(b / 2) + 1
            e[-1] = 0.0

            x[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e]
            y[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e]

            
            e = list(map(round, linspace(b/2, 0.0 , n-n2)))
            for i in range(n2, n):
                x[i] = uniform(-1.0, 1.0) * exp2(e[i - n2])
                y[i] = (uniform(-1.0, 1.0) * exp2(e[i - n2]) - DotExact(x, y)) / x[i]

            
            pairs = list(zip(x, y))
            shuffle(pairs)
            x, y = zip(*pairs)

            return DotExample(x, y, DotExact(x, y), Condition(x, y))

        def RelativeError(res, ex):
            x, y, target_sumprod, condition = ex
            n = DotExact(list(x) + [-res], list(y) + [1])
            return fabs(n / target_sumprod)

        def Trial(dotfunc, c, n):
            ex = GenDot(10, c)
            res = dotfunc(ex.x, ex.y)
            return RelativeError(res, ex)

        times = 1000          
        n = 20                
        c = 1e30              

        
        
        
        
        
        relative_err = median(Trial(math.sumprod, c, n) for i in range(times))
        self.assertLess(relative_err, 1e-16)

    def testModf(self):
        self.assertRaises(TypeError, math.modf)

        def testmodf(name, result, expected):
            (v1, v2), (e1, e2) = result, expected
            if abs(v1-e1) > eps or abs(v2-e2):
                self.fail('%s returned %r, expected %r'%\
                          (name, result, expected))

        testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
        testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))

        self.assertEqual(math.modf(INF), (0.0, INF))
        self.assertEqual(math.modf(NINF), (-0.0, NINF))

        modf_nan = math.modf(NAN)
        self.assertTrue(math.isnan(modf_nan[0]))
        self.assertTrue(math.isnan(modf_nan[1]))

    def testPow(self):
        self.assertRaises(TypeError, math.pow)
        self.ftest('pow(0,1)', math.pow(0,1), 0)
        self.ftest('pow(1,0)', math.pow(1,0), 1)
        self.ftest('pow(2,1)', math.pow(2,1), 2)
        self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
        self.assertEqual(math.pow(INF, 1), INF)
        self.assertEqual(math.pow(NINF, 1), NINF)
        self.assertEqual((math.pow(1, INF)), 1.)
        self.assertEqual((math.pow(1, NINF)), 1.)
        self.assertTrue(math.isnan(math.pow(NAN, 1)))
        self.assertTrue(math.isnan(math.pow(2, NAN)))
        self.assertTrue(math.isnan(math.pow(0, NAN)))
        self.assertEqual(math.pow(1, NAN), 1)
        self.assertRaises(OverflowError, math.pow, 1e+100, 1e+100)

        
        self.assertEqual(math.pow(0., INF), 0.)
        self.assertEqual(math.pow(0., 3.), 0.)
        self.assertEqual(math.pow(0., 2.3), 0.)
        self.assertEqual(math.pow(0., 2.), 0.)
        self.assertEqual(math.pow(0., 0.), 1.)
        self.assertEqual(math.pow(0., -0.), 1.)
        self.assertRaises(ValueError, math.pow, 0., -2.)
        self.assertRaises(ValueError, math.pow, 0., -2.3)
        self.assertRaises(ValueError, math.pow, 0., -3.)
        self.assertEqual(math.pow(0., NINF), INF)
        self.assertTrue(math.isnan(math.pow(0., NAN)))

        
        self.assertEqual(math.pow(INF, INF), INF)
        self.assertEqual(math.pow(INF, 3.), INF)
        self.assertEqual(math.pow(INF, 2.3), INF)
        self.assertEqual(math.pow(INF, 2.), INF)
        self.assertEqual(math.pow(INF, 0.), 1.)
        self.assertEqual(math.pow(INF, -0.), 1.)
        self.assertEqual(math.pow(INF, -2.), 0.)
        self.assertEqual(math.pow(INF, -2.3), 0.)
        self.assertEqual(math.pow(INF, -3.), 0.)
        self.assertEqual(math.pow(INF, NINF), 0.)
        self.assertTrue(math.isnan(math.pow(INF, NAN)))

        
        self.assertEqual(math.pow(-0., INF), 0.)
        self.assertEqual(math.pow(-0., 3.), -0.)
        self.assertEqual(math.pow(-0., 2.3), 0.)
        self.assertEqual(math.pow(-0., 2.), 0.)
        self.assertEqual(math.pow(-0., 0.), 1.)
        self.assertEqual(math.pow(-0., -0.), 1.)
        self.assertRaises(ValueError, math.pow, -0., -2.)
        self.assertRaises(ValueError, math.pow, -0., -2.3)
        self.assertRaises(ValueError, math.pow, -0., -3.)
        self.assertEqual(math.pow(-0., NINF), INF)
        self.assertTrue(math.isnan(math.pow(-0., NAN)))

        
        self.assertEqual(math.pow(NINF, INF), INF)
        self.assertEqual(math.pow(NINF, 3.), NINF)
        self.assertEqual(math.pow(NINF, 2.3), INF)
        self.assertEqual(math.pow(NINF, 2.), INF)
        self.assertEqual(math.pow(NINF, 0.), 1.)
        self.assertEqual(math.pow(NINF, -0.), 1.)
        self.assertEqual(math.pow(NINF, -2.), 0.)
        self.assertEqual(math.pow(NINF, -2.3), 0.)
        self.assertEqual(math.pow(NINF, -3.), -0.)
        self.assertEqual(math.pow(NINF, NINF), 0.)
        self.assertTrue(math.isnan(math.pow(NINF, NAN)))

        
        self.assertEqual(math.pow(-1., INF), 1.)
        self.assertEqual(math.pow(-1., 3.), -1.)
        self.assertRaises(ValueError, math.pow, -1., 2.3)
        self.assertEqual(math.pow(-1., 2.), 1.)
        self.assertEqual(math.pow(-1., 0.), 1.)
        self.assertEqual(math.pow(-1., -0.), 1.)
        self.assertEqual(math.pow(-1., -2.), 1.)
        self.assertRaises(ValueError, math.pow, -1., -2.3)
        self.assertEqual(math.pow(-1., -3.), -1.)
        self.assertEqual(math.pow(-1., NINF), 1.)
        self.assertTrue(math.isnan(math.pow(-1., NAN)))

        
        self.assertEqual(math.pow(1., INF), 1.)
        self.assertEqual(math.pow(1., 3.), 1.)
        self.assertEqual(math.pow(1., 2.3), 1.)
        self.assertEqual(math.pow(1., 2.), 1.)
        self.assertEqual(math.pow(1., 0.), 1.)
        self.assertEqual(math.pow(1., -0.), 1.)
        self.assertEqual(math.pow(1., -2.), 1.)
        self.assertEqual(math.pow(1., -2.3), 1.)
        self.assertEqual(math.pow(1., -3.), 1.)
        self.assertEqual(math.pow(1., NINF), 1.)
        self.assertEqual(math.pow(1., NAN), 1.)

        
        self.assertEqual(math.pow(2.3, 0.), 1.)
        self.assertEqual(math.pow(-2.3, 0.), 1.)
        self.assertEqual(math.pow(NAN, 0.), 1.)
        self.assertEqual(math.pow(2.3, -0.), 1.)
        self.assertEqual(math.pow(-2.3, -0.), 1.)
        self.assertEqual(math.pow(NAN, -0.), 1.)

        
        self.assertRaises(ValueError, math.pow, -1., 2.3)
        self.assertRaises(ValueError, math.pow, -15., -3.1)

        
        self.assertEqual(math.pow(1.9, NINF), 0.)
        self.assertEqual(math.pow(1.1, NINF), 0.)
        self.assertEqual(math.pow(0.9, NINF), INF)
        self.assertEqual(math.pow(0.1, NINF), INF)
        self.assertEqual(math.pow(-0.1, NINF), INF)
        self.assertEqual(math.pow(-0.9, NINF), INF)
        self.assertEqual(math.pow(-1.1, NINF), 0.)
        self.assertEqual(math.pow(-1.9, NINF), 0.)

        
        self.assertEqual(math.pow(1.9, INF), INF)
        self.assertEqual(math.pow(1.1, INF), INF)
        self.assertEqual(math.pow(0.9, INF), 0.)
        self.assertEqual(math.pow(0.1, INF), 0.)
        self.assertEqual(math.pow(-0.1, INF), 0.)
        self.assertEqual(math.pow(-0.9, INF), 0.)
        self.assertEqual(math.pow(-1.1, INF), INF)
        self.assertEqual(math.pow(-1.9, INF), INF)

        
        self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
        self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
        self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
        self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
        self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
        self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
        self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
        self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
        self.assertRaises(ValueError, math.pow, -2.0, -0.5)
        self.assertRaises(ValueError, math.pow, -2.0, 0.5)

        
        
        
        
        
        
        
        
        
        
        

    def testRadians(self):
        self.assertRaises(TypeError, math.radians)
        self.ftest('radians(180)', math.radians(180), math.pi)
        self.ftest('radians(90)', math.radians(90), math.pi/2)
        self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
        self.ftest('radians(0)', math.radians(0), 0)

    @requires_IEEE_754
    def testRemainder(self):
        from fractions import Fraction

        def validate_spec(x, y, r):
            
            fx, fy, fr = Fraction(x), Fraction(y), Fraction(r)
            
            self.assertLessEqual(abs(fr), abs(fy/2))
            
            n = (fx - fr) / fy
            self.assertEqual(n, int(n))
            if abs(fr) == abs(fy/2):
                
                self.assertEqual(n/2, int(n/2))

        
        testcases = [
            
            '-4.0 1 -0.0',
            '-3.8 1  0.8',
            '-3.0 1 -0.0',
            '-2.8 1 -0.8',
            '-2.0 1 -0.0',
            '-1.8 1  0.8',
            '-1.0 1 -0.0',
            '-0.8 1 -0.8',
            '-0.0 1 -0.0',
            ' 0.0 1  0.0',
            ' 0.8 1  0.8',
            ' 1.0 1  0.0',
            ' 1.8 1 -0.8',
            ' 2.0 1  0.0',
            ' 2.8 1  0.8',
            ' 3.0 1  0.0',
            ' 3.8 1 -0.8',
            ' 4.0 1  0.0',

            
            '0x0.0p+0 0x1.921fb54442d18p+2 0x0.0p+0',
            '0x1.921fb54442d18p+0 0x1.921fb54442d18p+2  0x1.921fb54442d18p+0',
            '0x1.921fb54442d17p+1 0x1.921fb54442d18p+2  0x1.921fb54442d17p+1',
            '0x1.921fb54442d18p+1 0x1.921fb54442d18p+2  0x1.921fb54442d18p+1',
            '0x1.921fb54442d19p+1 0x1.921fb54442d18p+2 -0x1.921fb54442d17p+1',
            '0x1.921fb54442d17p+2 0x1.921fb54442d18p+2 -0x0.0000000000001p+2',
            '0x1.921fb54442d18p+2 0x1.921fb54442d18p+2  0x0p0',
            '0x1.921fb54442d19p+2 0x1.921fb54442d18p+2  0x0.0000000000001p+2',
            '0x1.2d97c7f3321d1p+3 0x1.921fb54442d18p+2  0x1.921fb54442d14p+1',
            '0x1.2d97c7f3321d2p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d18p+1',
            '0x1.2d97c7f3321d3p+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
            '0x1.921fb54442d17p+3 0x1.921fb54442d18p+2 -0x0.0000000000001p+3',
            '0x1.921fb54442d18p+3 0x1.921fb54442d18p+2  0x0p0',
            '0x1.921fb54442d19p+3 0x1.921fb54442d18p+2  0x0.0000000000001p+3',
            '0x1.f6a7a2955385dp+3 0x1.921fb54442d18p+2  0x1.921fb54442d14p+1',
            '0x1.f6a7a2955385ep+3 0x1.921fb54442d18p+2  0x1.921fb54442d18p+1',
            '0x1.f6a7a2955385fp+3 0x1.921fb54442d18p+2 -0x1.921fb54442d14p+1',
            '0x1.1475cc9eedf00p+5 0x1.921fb54442d18p+2  0x1.921fb54442d10p+1',
            '0x1.1475cc9eedf01p+5 0x1.921fb54442d18p+2 -0x1.921fb54442d10p+1',

            
            ' 1  0.c  0.4',
            '-1  0.c -0.4',
            ' 1 -0.c  0.4',
            '-1 -0.c -0.4',
            ' 1.4  0.c -0.4',
            '-1.4  0.c  0.4',
            ' 1.4 -0.c -0.4',
            '-1.4 -0.c  0.4',

            
            
            '0x1.dp+1023 0x1.4p+1023  0x0.9p+1023',
            '0x1.ep+1023 0x1.4p+1023 -0x0.ap+1023',
            '0x1.fp+1023 0x1.4p+1023 -0x0.9p+1023',
        ]

        for case in testcases:
            with self.subTest(case=case):
                x_hex, y_hex, expected_hex = case.split()
                x = float.fromhex(x_hex)
                y = float.fromhex(y_hex)
                expected = float.fromhex(expected_hex)
                validate_spec(x, y, expected)
                actual = math.remainder(x, y)
                
                
                self.assertEqual(actual.hex(), expected.hex())

        
        
        
        tiny = float.fromhex('1p-1074')  
        for n in range(-25, 25):
            if n == 0:
                continue
            y = n * tiny
            for m in range(100):
                x = m * tiny
                actual = math.remainder(x, y)
                validate_spec(x, y, actual)
                actual = math.remainder(-x, y)
                validate_spec(-x, y, actual)

        
        
        for value in [NAN, 0.0, -0.0, 2.0, -2.3, NINF, INF]:
            self.assertIsNaN(math.remainder(NAN, value))
            self.assertIsNaN(math.remainder(value, NAN))

        
        for value in [-2.3, -0.0, 0.0, 2.3]:
            self.assertEqual(math.remainder(value, INF), value)
            self.assertEqual(math.remainder(value, NINF), value)

        
        
        for value in [NINF, -2.3, -0.0, 0.0, 2.3, INF]:
            with self.assertRaises(ValueError):
                math.remainder(INF, value)
            with self.assertRaises(ValueError):
                math.remainder(NINF, value)
            with self.assertRaises(ValueError):
                math.remainder(value, 0.0)
            with self.assertRaises(ValueError):
                math.remainder(value, -0.0)

    def testSin(self):
        self.assertRaises(TypeError, math.sin)
        self.ftest('sin(0)', math.sin(0), 0)
        self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
        self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
        try:
            self.assertTrue(math.isnan(math.sin(INF)))
            self.assertTrue(math.isnan(math.sin(NINF)))
        except ValueError:
            self.assertRaises(ValueError, math.sin, INF)
            self.assertRaises(ValueError, math.sin, NINF)
        self.assertTrue(math.isnan(math.sin(NAN)))

    def testSinh(self):
        self.assertRaises(TypeError, math.sinh)
        self.ftest('sinh(0)', math.sinh(0), 0)
        self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
        self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
        self.assertEqual(math.sinh(INF), INF)
        self.assertEqual(math.sinh(NINF), NINF)
        self.assertTrue(math.isnan(math.sinh(NAN)))

    def testSqrt(self):
        self.assertRaises(TypeError, math.sqrt)
        self.ftest('sqrt(0)', math.sqrt(0), 0)
        self.ftest('sqrt(0)', math.sqrt(0.0), 0.0)
        self.ftest('sqrt(2.5)', math.sqrt(2.5), 1.5811388300841898)
        self.ftest('sqrt(0.25)', math.sqrt(0.25), 0.5)
        self.ftest('sqrt(25.25)', math.sqrt(25.25), 5.024937810560445)
        self.ftest('sqrt(1)', math.sqrt(1), 1)
        self.ftest('sqrt(4)', math.sqrt(4), 2)
        self.assertEqual(math.sqrt(INF), INF)
        self.assertRaises(ValueError, math.sqrt, -1)
        self.assertRaises(ValueError, math.sqrt, NINF)
        self.assertTrue(math.isnan(math.sqrt(NAN)))

    def testTan(self):
        self.assertRaises(TypeError, math.tan)
        self.ftest('tan(0)', math.tan(0), 0)
        self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
        self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
        try:
            self.assertTrue(math.isnan(math.tan(INF)))
            self.assertTrue(math.isnan(math.tan(NINF)))
        except:
            self.assertRaises(ValueError, math.tan, INF)
            self.assertRaises(ValueError, math.tan, NINF)
        self.assertTrue(math.isnan(math.tan(NAN)))

    def testTanh(self):
        self.assertRaises(TypeError, math.tanh)
        self.ftest('tanh(0)', math.tanh(0), 0)
        self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0,
                   abs_tol=math.ulp(1))
        self.ftest('tanh(inf)', math.tanh(INF), 1)
        self.ftest('tanh(-inf)', math.tanh(NINF), -1)
        self.assertTrue(math.isnan(math.tanh(NAN)))

    @requires_IEEE_754
    def testTanhSign(self):
        
        self.assertEqual(math.tanh(-0.), -0.)
        self.assertEqual(math.copysign(1., math.tanh(-0.)),
                         math.copysign(1., -0.))

    def test_trunc(self):
        self.assertEqual(math.trunc(1), 1)
        self.assertEqual(math.trunc(-1), -1)
        self.assertEqual(type(math.trunc(1)), int)
        self.assertEqual(type(math.trunc(1.5)), int)
        self.assertEqual(math.trunc(1.5), 1)
        self.assertEqual(math.trunc(-1.5), -1)
        self.assertEqual(math.trunc(1.999999), 1)
        self.assertEqual(math.trunc(-1.999999), -1)
        self.assertEqual(math.trunc(-0.999999), -0)
        self.assertEqual(math.trunc(-100.999), -100)

        class TestTrunc:
            def __trunc__(self):
                return 23
        class FloatTrunc(float):
            def __trunc__(self):
                return 23
        class TestNoTrunc:
            pass
        class TestBadTrunc:
            __trunc__ = BadDescr()

        self.assertEqual(math.trunc(TestTrunc()), 23)
        self.assertEqual(math.trunc(FloatTrunc()), 23)

        self.assertRaises(TypeError, math.trunc)
        self.assertRaises(TypeError, math.trunc, 1, 2)
        self.assertRaises(TypeError, math.trunc, FloatLike(23.5))
        self.assertRaises(TypeError, math.trunc, TestNoTrunc())
        self.assertRaises(ValueError, math.trunc, TestBadTrunc())

    def testIsfinite(self):
        self.assertTrue(math.isfinite(0.0))
        self.assertTrue(math.isfinite(-0.0))
        self.assertTrue(math.isfinite(1.0))
        self.assertTrue(math.isfinite(-1.0))
        self.assertFalse(math.isfinite(float("nan")))
        self.assertFalse(math.isfinite(float("inf")))
        self.assertFalse(math.isfinite(float("-inf")))

    def testIsnan(self):
        self.assertTrue(math.isnan(float("nan")))
        self.assertTrue(math.isnan(float("-nan")))
        self.assertTrue(math.isnan(float("inf") * 0.))
        self.assertFalse(math.isnan(float("inf")))
        self.assertFalse(math.isnan(0.))
        self.assertFalse(math.isnan(1.))

    def testIsinf(self):
        self.assertTrue(math.isinf(float("inf")))
        self.assertTrue(math.isinf(float("-inf")))
        self.assertTrue(math.isinf(1E400))
        self.assertTrue(math.isinf(-1E400))
        self.assertFalse(math.isinf(float("nan")))
        self.assertFalse(math.isinf(0.))
        self.assertFalse(math.isinf(1.))

    def test_nan_constant(self):
        
        self.assertTrue(math.isnan(math.nan))
        self.assertEqual(math.copysign(1., math.nan), 1.)

    def test_inf_constant(self):
        self.assertTrue(math.isinf(math.inf))
        self.assertGreater(math.inf, 0.0)
        self.assertEqual(math.inf, float("inf"))
        self.assertEqual(-math.inf, float("-inf"))

    
    
    
    
    
    @unittest.skipUnless(verbose, 'requires verbose mode')
    def test_exceptions(self):
        try:
            x = math.exp(-1000000000)
        except:
            
            
            self.fail("underflowing exp() should not have raised "
                        "an exception")
        if x != 0:
            self.fail("underflowing exp() should have returned 0")

        
        
        try:
            x = math.exp(1000000000)
        except OverflowError:
            pass
        else:
            self.fail("overflowing exp() didn't trigger OverflowError")

        
        
        
        
        try:
            x = math.sqrt(-1.0)
        except ValueError:
            pass
        else:
            self.fail("sqrt(-1) didn't raise ValueError")

    @requires_IEEE_754
    def test_testfile(self):
        
        
        SKIP_ON_TIGER = {'tan0064'}

        osx_version = None
        if sys.platform == 'darwin':
            version_txt = platform.mac_ver()[0]
            try:
                osx_version = tuple(map(int, version_txt.split('.')))
            except ValueError:
                pass

        fail_fmt = "{}: {}({!r}): {}"

        failures = []
        for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
            
            if ai != 0.0 or ei != 0.0:
                continue
            if fn in ['rect', 'polar']:
                
                continue
            
            if osx_version is not None and osx_version < (10, 5):
                if id in SKIP_ON_TIGER:
                    continue

            func = getattr(math, fn)

            if 'invalid' in flags or 'divide-by-zero' in flags:
                er = 'ValueError'
            elif 'overflow' in flags:
                er = 'OverflowError'

            try:
                result = func(ar)
            except ValueError:
                result = 'ValueError'
            except OverflowError:
                result = 'OverflowError'

            
            ulp_tol, abs_tol = 5, 0.0

            failure = result_check(er, result, ulp_tol, abs_tol)
            if failure is None:
                continue

            msg = fail_fmt.format(id, fn, ar, failure)
            failures.append(msg)

        if failures:
            self.fail('Failures in test_testfile:\n  ' +
                      '\n  '.join(failures))

    @requires_IEEE_754
    def test_mtestfile(self):
        fail_fmt = "{}: {}({!r}): {}"

        failures = []
        for id, fn, arg, expected, flags in parse_mtestfile(math_testcases):
            func = getattr(math, fn)

            if 'invalid' in flags or 'divide-by-zero' in flags:
                expected = 'ValueError'
            elif 'overflow' in flags:
                expected = 'OverflowError'

            try:
                got = func(arg)
            except ValueError:
                got = 'ValueError'
            except OverflowError:
                got = 'OverflowError'

            
            ulp_tol, abs_tol = 5, 0.0

            
            if fn == 'gamma':
                
                
                
                ulp_tol = 20

            elif fn == 'lgamma':
                
                
                
                
                abs_tol = 1e-15

            elif fn == 'erfc' and arg >= 0.0:
                
                
                
                
                
                
                
                
                
                
                
                if arg < 1.0:
                    ulp_tol = 10
                elif arg < 10.0:
                    ulp_tol = 100
                else:
                    ulp_tol = 1000

            failure = result_check(expected, got, ulp_tol, abs_tol)
            if failure is None:
                continue

            msg = fail_fmt.format(id, fn, arg, failure)
            failures.append(msg)

        if failures:
            self.fail('Failures in test_mtestfile:\n  ' +
                      '\n  '.join(failures))

    def test_prod(self):
        from fractions import Fraction as F

        prod = math.prod
        self.assertEqual(prod([]), 1)
        self.assertEqual(prod([], start=5), 5)
        self.assertEqual(prod(list(range(2,8))), 5040)
        self.assertEqual(prod(iter(list(range(2,8)))), 5040)
        self.assertEqual(prod(range(1, 10), start=10), 3628800)

        self.assertEqual(prod([1, 2, 3, 4, 5]), 120)
        self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0)
        self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0)
        self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0)
        self.assertEqual(prod([1., F(3, 2)]), 1.5)

        
        class BadMultiply:
            def __rmul__(self, other):
                raise RuntimeError
        with self.assertRaises(RuntimeError):
            prod([10., BadMultiply()])

        
        self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32)
        
        self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32))

        self.assertRaises(TypeError, prod)
        self.assertRaises(TypeError, prod, 42)
        self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
        self.assertRaises(TypeError, prod, ['a', 'b', 'c'], start='')
        self.assertRaises(TypeError, prod, [b'a', b'c'], start=b'')
        values = [bytearray(b'a'), bytearray(b'b')]
        self.assertRaises(TypeError, prod, values, start=bytearray(b''))
        self.assertRaises(TypeError, prod, [[1], [2], [3]])
        self.assertRaises(TypeError, prod, [{2:3}])
        self.assertRaises(TypeError, prod, [{2:3}]*2, start={2:3})
        self.assertRaises(TypeError, prod, [[1], [2], [3]], start=[])

        
        self.assertEqual(prod([2, 3], start='ab'), 'abababababab')
        self.assertEqual(prod([2, 3], start=[1, 2]), [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2])
        self.assertEqual(prod([], start={2: 3}), {2:3})

        with self.assertRaises(TypeError):
            prod([10, 20], 1)     

        self.assertEqual(prod([0, 1, 2, 3]), 0)
        self.assertEqual(prod([1, 0, 2, 3]), 0)
        self.assertEqual(prod([1, 2, 3, 0]), 0)

        def _naive_prod(iterable, start=1):
            for elem in iterable:
                start *= elem
            return start

        

        iterable = range(1, 10000)
        self.assertEqual(prod(iterable), _naive_prod(iterable))
        iterable = range(-10000, -1)
        self.assertEqual(prod(iterable), _naive_prod(iterable))
        iterable = range(-1000, 1000)
        self.assertEqual(prod(iterable), 0)

        

        iterable = [float(x) for x in range(1, 1000)]
        self.assertEqual(prod(iterable), _naive_prod(iterable))
        iterable = [float(x) for x in range(-1000, -1)]
        self.assertEqual(prod(iterable), _naive_prod(iterable))
        iterable = [float(x) for x in range(-1000, 1000)]
        self.assertIsNaN(prod(iterable))

        

        self.assertIsNaN(prod([1, 2, 3, float("nan"), 2, 3]))
        self.assertIsNaN(prod([1, 0, float("nan"), 2, 3]))
        self.assertIsNaN(prod([1, float("nan"), 0, 3]))
        self.assertIsNaN(prod([1, float("inf"), float("nan"),3]))
        self.assertIsNaN(prod([1, float("-inf"), float("nan"),3]))
        self.assertIsNaN(prod([1, float("nan"), float("inf"),3]))
        self.assertIsNaN(prod([1, float("nan"), float("-inf"),3]))

        self.assertEqual(prod([1, 2, 3, float('inf'),-3,4]), float('-inf'))
        self.assertEqual(prod([1, 2, 3, float('-inf'),-3,4]), float('inf'))

        self.assertIsNaN(prod([1,2,0,float('inf'), -3, 4]))
        self.assertIsNaN(prod([1,2,0,float('-inf'), -3, 4]))
        self.assertIsNaN(prod([1, 2, 3, float('inf'), -3, 0, 3]))
        self.assertIsNaN(prod([1, 2, 3, float('-inf'), -3, 0, 2]))

        

        self.assertEqual(type(prod([1, 2, 3, 4, 5, 6])), int)
        self.assertEqual(type(prod([1, 2.0, 3, 4, 5, 6])), float)
        self.assertEqual(type(prod(range(1, 10000))), int)
        self.assertEqual(type(prod(range(1, 10000), start=1.0)), float)
        self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
                         decimal.Decimal)

    def testPerm(self):
        perm = math.perm
        factorial = math.factorial
        
        for n in range(500):
            for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)):
                self.assertEqual(perm(n, k),
                                 factorial(n) // factorial(n - k))

        
        for n in range(1, 100):
            for k in range(1, n):
                self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))

        
        for n in range(1, 100):
            self.assertEqual(perm(n, 0), 1)
            self.assertEqual(perm(n, 1), n)
            self.assertEqual(perm(n, n), factorial(n))

        
        for n in range(20):
            self.assertEqual(perm(n), factorial(n))
            self.assertEqual(perm(n, None), factorial(n))

        
        
        self.assertRaises(TypeError, perm, 10, 1.0)
        self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
        self.assertRaises(TypeError, perm, 10, "1")
        self.assertRaises(TypeError, perm, 10.0, 1)
        self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
        self.assertRaises(TypeError, perm, "10", 1)

        self.assertRaises(TypeError, perm)
        self.assertRaises(TypeError, perm, 10, 1, 3)
        self.assertRaises(TypeError, perm)

        
        self.assertRaises(ValueError, perm, -1, 1)
        self.assertRaises(ValueError, perm, -2**1000, 1)
        self.assertRaises(ValueError, perm, 1, -1)
        self.assertRaises(ValueError, perm, 1, -2**1000)

        
        self.assertEqual(perm(1, 2), 0)
        self.assertEqual(perm(1, 2**1000), 0)

        n = 2**1000
        self.assertEqual(perm(n, 0), 1)
        self.assertEqual(perm(n, 1), n)
        self.assertEqual(perm(n, 2), n * (n-1))
        if support.check_impl_detail(cpython=True):
            self.assertRaises(OverflowError, perm, n, n)

        for n, k in (True, True), (True, False), (False, False):
            self.assertEqual(perm(n, k), 1)
            self.assertIs(type(perm(n, k)), int)
        self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
        self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
        for k in range(3):
            self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
            self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)

    def testComb(self):
        comb = math.comb
        factorial = math.factorial
        
        for n in range(500):
            for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)):
                self.assertEqual(comb(n, k), factorial(n)
                    // (factorial(k) * factorial(n - k)))

        
        for n in range(1, 100):
            for k in range(1, n):
                self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))

        
        for n in range(100):
            self.assertEqual(comb(n, 0), 1)
            self.assertEqual(comb(n, n), 1)

        for n in range(1, 100):
            self.assertEqual(comb(n, 1), n)
            self.assertEqual(comb(n, n - 1), n)

        
        for n in range(100):
            for k in range(n // 2):
                self.assertEqual(comb(n, k), comb(n, n - k))

        
        
        self.assertRaises(TypeError, comb, 10, 1.0)
        self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
        self.assertRaises(TypeError, comb, 10, "1")
        self.assertRaises(TypeError, comb, 10.0, 1)
        self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
        self.assertRaises(TypeError, comb, "10", 1)

        self.assertRaises(TypeError, comb, 10)
        self.assertRaises(TypeError, comb, 10, 1, 3)
        self.assertRaises(TypeError, comb)

        
        self.assertRaises(ValueError, comb, -1, 1)
        self.assertRaises(ValueError, comb, -2**1000, 1)
        self.assertRaises(ValueError, comb, 1, -1)
        self.assertRaises(ValueError, comb, 1, -2**1000)

        
        self.assertEqual(comb(1, 2), 0)
        self.assertEqual(comb(1, 2**1000), 0)

        n = 2**1000
        self.assertEqual(comb(n, 0), 1)
        self.assertEqual(comb(n, 1), n)
        self.assertEqual(comb(n, 2), n * (n-1) // 2)
        self.assertEqual(comb(n, n), 1)
        self.assertEqual(comb(n, n-1), n)
        self.assertEqual(comb(n, n-2), n * (n-1) // 2)
        if support.check_impl_detail(cpython=True):
            self.assertRaises(OverflowError, comb, n, n//2)

        for n, k in (True, True), (True, False), (False, False):
            self.assertEqual(comb(n, k), 1)
            self.assertIs(type(comb(n, k)), int)
        self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
        self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
        for k in range(3):
            self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
            self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)

    @requires_IEEE_754
    def test_nextafter(self):
        
        self.assertEqual(math.nextafter(4503599627370496.0, -INF),
                         4503599627370495.5)
        self.assertEqual(math.nextafter(4503599627370496.0, INF),
                         4503599627370497.0)
        self.assertEqual(math.nextafter(9223372036854775808.0, 0.0),
                         9223372036854774784.0)
        self.assertEqual(math.nextafter(-9223372036854775808.0, 0.0),
                         -9223372036854774784.0)

        
        self.assertEqual(math.nextafter(1.0, -INF),
                         float.fromhex('0x1.fffffffffffffp-1'))
        self.assertEqual(math.nextafter(1.0, INF),
                         float.fromhex('0x1.0000000000001p+0'))
        self.assertEqual(math.nextafter(1.0, -INF, steps=1),
                         float.fromhex('0x1.fffffffffffffp-1'))
        self.assertEqual(math.nextafter(1.0, INF, steps=1),
                         float.fromhex('0x1.0000000000001p+0'))
        self.assertEqual(math.nextafter(1.0, -INF, steps=3),
                         float.fromhex('0x1.ffffffffffffdp-1'))
        self.assertEqual(math.nextafter(1.0, INF, steps=3),
                         float.fromhex('0x1.0000000000003p+0'))

        
        for steps in range(1, 5):
            self.assertEqual(math.nextafter(2.0, 2.0, steps=steps), 2.0)
            self.assertEqualSign(math.nextafter(-0.0, +0.0, steps=steps), +0.0)
            self.assertEqualSign(math.nextafter(+0.0, -0.0, steps=steps), -0.0)

        
        smallest_subnormal = sys.float_info.min * sys.float_info.epsilon
        self.assertEqual(math.nextafter(+0.0, INF), smallest_subnormal)
        self.assertEqual(math.nextafter(-0.0, INF), smallest_subnormal)
        self.assertEqual(math.nextafter(+0.0, -INF), -smallest_subnormal)
        self.assertEqual(math.nextafter(-0.0, -INF), -smallest_subnormal)
        self.assertEqualSign(math.nextafter(smallest_subnormal, +0.0), +0.0)
        self.assertEqualSign(math.nextafter(-smallest_subnormal, +0.0), -0.0)
        self.assertEqualSign(math.nextafter(smallest_subnormal, -0.0), +0.0)
        self.assertEqualSign(math.nextafter(-smallest_subnormal, -0.0), -0.0)

        
        largest_normal = sys.float_info.max
        self.assertEqual(math.nextafter(INF, 0.0), largest_normal)
        self.assertEqual(math.nextafter(-INF, 0.0), -largest_normal)
        self.assertEqual(math.nextafter(largest_normal, INF), INF)
        self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)

        
        self.assertIsNaN(math.nextafter(NAN, 1.0))
        self.assertIsNaN(math.nextafter(1.0, NAN))
        self.assertIsNaN(math.nextafter(NAN, NAN))

        self.assertEqual(1.0, math.nextafter(1.0, INF, steps=0))
        with self.assertRaises(ValueError):
            math.nextafter(1.0, INF, steps=-1)


    @requires_IEEE_754
    def test_ulp(self):
        self.assertEqual(math.ulp(1.0), sys.float_info.epsilon)
        
        self.assertEqual(math.ulp(2 ** 52), 1.0)
        self.assertEqual(math.ulp(2 ** 53), 2.0)
        self.assertEqual(math.ulp(2 ** 64), 4096.0)

        
        self.assertEqual(math.ulp(0.0),
                         sys.float_info.min * sys.float_info.epsilon)
        self.assertEqual(math.ulp(FLOAT_MAX),
                         FLOAT_MAX - math.nextafter(FLOAT_MAX, -INF))

        
        self.assertEqual(math.ulp(INF), INF)
        self.assertIsNaN(math.ulp(math.nan))

        
        for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
            with self.subTest(x=x):
                self.assertEqual(math.ulp(-x), math.ulp(x))

    def test_issue39871(self):
        
        
        class F:
            def __float__(self):
                self.converted = True
                1/0
        for func in math.atan2, math.copysign, math.remainder:
            y = F()
            with self.assertRaises(TypeError):
                func("not a number", y)

            
            
            self.assertFalse(getattr(y, "converted", False))

    def test_input_exceptions(self):
        self.assertRaises(TypeError, math.exp, "spam")
        self.assertRaises(TypeError, math.erf, "spam")
        self.assertRaises(TypeError, math.atan2, "spam", 1.0)
        self.assertRaises(TypeError, math.atan2, 1.0, "spam")
        self.assertRaises(TypeError, math.atan2, 1.0)
        self.assertRaises(TypeError, math.atan2, 1.0, 2.0, 3.0)

    

    def assertIsNaN(self, value):
        if not math.isnan(value):
            self.fail("Expected a NaN, got {!r}.".format(value))

    def assertEqualSign(self, x, y):
        
        self.assertEqual(x, y)
        self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))


class IsCloseTests(unittest.TestCase):
    isclose = math.isclose  

    def assertIsClose(self, a, b, *args, **kwargs):
        self.assertTrue(self.isclose(a, b, *args, **kwargs),
                        msg="%s and %s should be close!" % (a, b))

    def assertIsNotClose(self, a, b, *args, **kwargs):
        self.assertFalse(self.isclose(a, b, *args, **kwargs),
                         msg="%s and %s should not be close!" % (a, b))

    def assertAllClose(self, examples, *args, **kwargs):
        for a, b in examples:
            self.assertIsClose(a, b, *args, **kwargs)

    def assertAllNotClose(self, examples, *args, **kwargs):
        for a, b in examples:
            self.assertIsNotClose(a, b, *args, **kwargs)

    def test_negative_tolerances(self):
        
        with self.assertRaises(ValueError):
            self.assertIsClose(1, 1, rel_tol=-1e-100)
        with self.assertRaises(ValueError):
            self.assertIsClose(1, 1, rel_tol=1e-100, abs_tol=-1e10)

    def test_identical(self):
        
        identical_examples = [(2.0, 2.0),
                              (0.1e200, 0.1e200),
                              (1.123e-300, 1.123e-300),
                              (12345, 12345.0),
                              (0.0, -0.0),
                              (345678, 345678)]
        self.assertAllClose(identical_examples, rel_tol=0.0, abs_tol=0.0)

    def test_eight_decimal_places(self):
        
        eight_decimal_places_examples = [(1e8, 1e8 + 1),
                                         (-1e-8, -1.000000009e-8),
                                         (1.12345678, 1.12345679)]
        self.assertAllClose(eight_decimal_places_examples, rel_tol=1e-8)
        self.assertAllNotClose(eight_decimal_places_examples, rel_tol=1e-9)

    def test_near_zero(self):
        
        near_zero_examples = [(1e-9, 0.0),
                              (-1e-9, 0.0),
                              (-1e-150, 0.0)]
        
        self.assertAllNotClose(near_zero_examples, rel_tol=0.9)
        
        self.assertAllClose(near_zero_examples, abs_tol=1e-8)

    def test_identical_infinite(self):
        
        self.assertIsClose(INF, INF)
        self.assertIsClose(INF, INF, abs_tol=0.0)
        self.assertIsClose(NINF, NINF)
        self.assertIsClose(NINF, NINF, abs_tol=0.0)

    def test_inf_ninf_nan(self):
        
        not_close_examples = [(NAN, NAN),
                              (NAN, 1e-100),
                              (1e-100, NAN),
                              (INF, NAN),
                              (NAN, INF),
                              (INF, NINF),
                              (INF, 1.0),
                              (1.0, INF),
                              (INF, 1e308),
                              (1e308, INF)]
        
        self.assertAllNotClose(not_close_examples, abs_tol=0.999999999999999)

    def test_zero_tolerance(self):
        
        zero_tolerance_close_examples = [(1.0, 1.0),
                                         (-3.4, -3.4),
                                         (-1e-300, -1e-300)]
        self.assertAllClose(zero_tolerance_close_examples, rel_tol=0.0)

        zero_tolerance_not_close_examples = [(1.0, 1.000000000000001),
                                             (0.99999999999999, 1.0),
                                             (1.0e200, .999999999999999e200)]
        self.assertAllNotClose(zero_tolerance_not_close_examples, rel_tol=0.0)

    def test_asymmetry(self):
        
        self.assertAllClose([(9, 10), (10, 9)], rel_tol=0.1)

    def test_integers(self):
        
        integer_examples = [(100000001, 100000000),
                            (123456789, 123456788)]

        self.assertAllClose(integer_examples, rel_tol=1e-8)
        self.assertAllNotClose(integer_examples, rel_tol=1e-9)

    def test_decimals(self):
        
        from decimal import Decimal

        decimal_examples = [(Decimal('1.00000001'), Decimal('1.0')),
                            (Decimal('1.00000001e-20'), Decimal('1.0e-20')),
                            (Decimal('1.00000001e-100'), Decimal('1.0e-100')),
                            (Decimal('1.00000001e20'), Decimal('1.0e20'))]
        self.assertAllClose(decimal_examples, rel_tol=1e-8)
        self.assertAllNotClose(decimal_examples, rel_tol=1e-9)

    def test_fractions(self):
        
        from fractions import Fraction

        fraction_examples = [
            (Fraction(1, 100000000) + 1, Fraction(1)),
            (Fraction(100000001), Fraction(100000000)),
            (Fraction(10**8 + 1, 10**28), Fraction(1, 10**20))]
        self.assertAllClose(fraction_examples, rel_tol=1e-8)
        self.assertAllNotClose(fraction_examples, rel_tol=1e-9)


def load_tests(loader, tests, pattern):
    from doctest import DocFileSuite
    tests.addTest(DocFileSuite(os.path.join("mathdata", "ieee754.txt")))
    return tests

if __name__ == '__main__':
    unittest.main()