From f05d33913e5a870589d0808f8435334dbc4ae9ed Mon Sep 17 00:00:00 2001 From: nathanhack Date: Mon, 29 Jul 2019 13:30:12 -0400 Subject: [PATCH] Fixed a bug in Atan. Did not correctly handle when input is a large negative value. (#135) * corrected the last digit of a test expected value (sourced by wolframaplpha.com for correctness) * fix a bug when the values are large negative values and added tests --- math/arccosine_test.go | 2 +- math/arctangent.go | 6 ++++++ math/arctangent_test.go | 40 ++++++++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/math/arccosine_test.go b/math/arccosine_test.go index 6c19c59..bbb72a9 100644 --- a/math/arccosine_test.go +++ b/math/arccosine_test.go @@ -14,7 +14,7 @@ func TestAcos(t *testing.T) { x, r string }{ 0: {"-1.00", "3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068"}, - 1: {"-.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "3.141592653589793238462643383279502884197169399375091678839320861357328389398966901647249128623363298"}, + 1: {"-.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "3.141592653589793238462643383279502884197169399375091678839320861357328389398966901647249128623363299"}, 2: {"-0.50", "2.094395102393195492308428922186335256131446266250070547316629728205210937524139332418689883561411379"}, 3: {"0", "1.570796326794896619231321691639751442098584699687552910487472296153908203143104499314017412671058534"}, 4: {"0.5", "1.047197551196597746154214461093167628065723133125035273658314864102605468762069666209344941780705689"}, diff --git a/math/arctangent.go b/math/arctangent.go index 4e4af12..c1c6d20 100644 --- a/math/arctangent.go +++ b/math/arctangent.go @@ -150,6 +150,12 @@ func Atan(z, x *decimal.Big) *decimal.Big { return z } + //when x <-1 we use -atan(-x) instead + if x.Cmp(negone) < 0 { + Atan(z, new(decimal.Big).Neg(x)) + return z.Neg(z) + } + y, ySq, ySqPlus1, segment, halfed := prepAtan(z, x, ctx) // z == y, maybe. result := BinarySplitDynamic(ctx, func(_ uint64) *decimal.Big { return y }, diff --git a/math/arctangent_test.go b/math/arctangent_test.go index 976396c..68967e3 100644 --- a/math/arctangent_test.go +++ b/math/arctangent_test.go @@ -16,16 +16,18 @@ func TestAtan(t *testing.T) { for i, tt := range [...]struct { x, r string }{ - 0: {"0", "0"}, - 1: {".500", "0.4636476090008061162142562314612144020285370542861202638109330887201978641657417053006002839848878926"}, - 2: {"-.500", "-0.4636476090008061162142562314612144020285370542861202638109330887201978641657417053006002839848878926"}, - 3: {".9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669"}, - 4: {"-.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "-0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669"}, - 5: {"1.00", "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292670"}, - 6: {"-1.00", "-0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292670"}, - 7: {".999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773461152387645557931339852032120279362571025675484630276389"}, - 8: {"100.0", "1.560796660108231381024981575430471893537215347143176270859532877957451649939045719334570767484384444"}, - 9: {"0." + strings.Repeat("9", 1000), "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669955370216283205766617734611523876455579313398520321202793625710256754846302763899111557372387325954911072027439164833615321189120584466957913178004772864121417308650871526135816620533484018150622853184311467516515788970437203802302407073135229288410919731475900028326326372051166303460367379853779023582643175914398979882730465293454831529482762796370186155949906873918379714381812228069845457529872824584183406101641607715053487365988061842976755449652359256926348042940732941880961687046169173512830001420317863158902069464428356894474022934092946803671102253062383575366373963427626980699223147308855049890280322554902160086045399534074436928274901296768028374999995932445124877649329332040240796487561148638367270756606305770633361712588154827970427525007844596882216468833020953551542944172868258995633726071888671827898907159705884468984379894454644451330428067016532504819691527989773041050497"}, + 0: {"0", "0"}, + 1: {".500", "0.4636476090008061162142562314612144020285370542861202638109330887201978641657417053006002839848878926"}, + 2: {"-.500", "-0.4636476090008061162142562314612144020285370542861202638109330887201978641657417053006002839848878926"}, + 3: {".9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669"}, + 4: {"-.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "-0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669"}, + 5: {"1.00", "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292670"}, + 6: {"-1.00", "-0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292670"}, + 7: {".999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773461152387645557931339852032120279362571025675484630276389"}, + 8: {"100.0", "1.560796660108231381024981575430471893537215347143176270859532877957451649939045719334570767484384444"}, + 9: {"0." + strings.Repeat("9", 1000), "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669955370216283205766617734611523876455579313398520321202793625710256754846302763899111557372387325954911072027439164833615321189120584466957913178004772864121417308650871526135816620533484018150622853184311467516515788970437203802302407073135229288410919731475900028326326372051166303460367379853779023582643175914398979882730465293454831529482762796370186155949906873918379714381812228069845457529872824584183406101641607715053487365988061842976755449652359256926348042940732941880961687046169173512830001420317863158902069464428356894474022934092946803671102253062383575366373963427626980699223147308855049890280322554902160086045399534074436928274901296768028374999995932445124877649329332040240796487561148638367270756606305770633361712588154827970427525007844596882216468833020953551542944172868258995633726071888671827898907159705884468984379894454644451330428067016532504819691527989773041050497"}, + 10: {"100", "1.560796660108231381024981575430471893537215347143176270859532877957451649939045719334570767484384444"}, + 11: {"-100", "-1.560796660108231381024981575430471893537215347143176270859532877957451649939045719334570767484384444"}, } { t.Run(strconv.Itoa(i), func(t *testing.T) { z := decimal.WithPrecision(N) @@ -129,6 +131,24 @@ func TestAtan2(t *testing.T) { // Atan2(y<0, x<0) = Atan(y/x) - pi 34: {"-1", "-1", neg(_3pi_4, N)}, + + // tests in all the quandrants + 35: {"1", "1", "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669955370216283205766617734611523876455579313398520321202793625710256754846302763899111557372387325954911072027439164833615321189120584466957913178004772864121417308650871526135816620533484018150622853184311467516515788970437203802302407073135229288410919731475900028326326372051166303460367379853779023582643175914398979882730465293454831529482762796370186155949906873918379714381812228069845457529872824584183406101641607715053487365988061842976755449652359256926348042940732941880961687046169173512830001420317863158902069464428356894474022934092946803671102253062383575366373963427626980699223147308855049890280322554902160086045399534074436928274901296768028374999995932445124877649329332040240796487561148638367270756606305770633361712588154827970427525007844596882216468833020953551542944172868258995633726071888671827898907159705884468984379894454644451330428067016532504819691527989773041050497"}, + 36: {"-1", "1", "-0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669955370216283205766617734611523876455579313398520321202793625710256754846302763899111557372387325954911072027439164833615321189120584466957913178004772864121417308650871526135816620533484018150622853184311467516515788970437203802302407073135229288410919731475900028326326372051166303460367379853779023582643175914398979882730465293454831529482762796370186155949906873918379714381812228069845457529872824584183406101641607715053487365988061842976755449652359256926348042940732941880961687046169173512830001420317863158902069464428356894474022934092946803671102253062383575366373963427626980699223147308855049890280322554902160086045399534074436928274901296768028374999995932445124877649329332040240796487561148638367270756606305770633361712588154827970427525007844596882216468833020953551542944172868258995633726071888671827898907159705884468984379894454644451330428067016532504819691527989773041050497"}, + 37: {"-1", "-1", "-2.356194490192344928846982537459627163147877049531329365731208444230862304714656748971026119006587800986611064884961729985320383457162936673794019556096360838087713077026453890829169733467211716197786473321608231749450084596356736175340087373953401431859236425192595261457840744986160045205445186855955293440254954736691131161140690722121940568786523275919442770008497897911615349891038110213956133707074792952774319693964819139588036449458844828838911055846784972062175513914314543668420953637258961847375255021830492482314516046209796418552893026634895707777077904412882219882564288506113850752053849000426095358947670620839328507068342206880227884041101330675918715072609912189028288094209766944192656514967084096766470648025813619860222331078482470389030408512499998779733537463294798799612072238946268344591510181226981891731190008513776446448391128257502353379064664940649906286065462883251860477698690117821566601548369672147911765340695313968336393335399128420104959751445907458396931912315149"}, + 38: {"1", "-1", "2.356194490192344928846982537459627163147877049531329365731208444230862304714656748971026119006587800986611064884961729985320383457162936673794019556096360838087713077026453890829169733467211716197786473321608231749450084596356736175340087373953401431859236425192595261457840744986160045205445186855955293440254954736691131161140690722121940568786523275919442770008497897911615349891038110213956133707074792952774319693964819139588036449458844828838911055846784972062175513914314543668420953637258961847375255021830492482314516046209796418552893026634895707777077904412882219882564288506113850752053849000426095358947670620839328507068342206880227884041101330675918715072609912189028288094209766944192656514967084096766470648025813619860222331078482470389030408512499998779733537463294798799612072238946268344591510181226981891731190008513776446448391128257502353379064664940649906286065462883251860477698690117821566601548369672147911765340695313968336393335399128420104959751445907458396931912315149"}, + + // bigger values + 39: {"-2", "1", "-1.107148717794090503017065460178537040070047645401432646676539207433710338977362794013417128686170641434544191005450315810041104123150279960391149134120134938005805785186089159020277066323548671948337093046927250546427929146225306917409377626797415839477802650155236302150617431245551139595028661343071619620451122700330078743309876584050730556855033496160917167182032143557952418577001974141917867556092072396370970780081569293338989816628296388058648735549977420441253262448910061152421541607476658452967630519135912384306883380785499443665836032138897074518792365757298891993783946015848255470901612250351968711897831227460369643896101759549486816806083720841936706092318858507663251672427870156094793691467362050699710474237952805081154791173982305447826322952479276589220603404510278110198878003520641243073406563806386080606837666971733818544308606074699132134849976299998223302991267312103414276992963861911174853919055822470048763842269788306246988883221693259159049588694161190408677435945636"}, + 40: {"2", "1", "1.107148717794090503017065460178537040070047645401432646676539207433710338977362794013417128686170641434544191005450315810041104123150279960391149134120134938005805785186089159020277066323548671948337093046927250546427929146225306917409377626797415839477802650155236302150617431245551139595028661343071619620451122700330078743309876584050730556855033496160917167182032143557952418577001974141917867556092072396370970780081569293338989816628296388058648735549977420441253262448910061152421541607476658452967630519135912384306883380785499443665836032138897074518792365757298891993783946015848255470901612250351968711897831227460369643896101759549486816806083720841936706092318858507663251672427870156094793691467362050699710474237952805081154791173982305447826322952479276589220603404510278110198878003520641243073406563806386080606837666971733818544308606074699132134849976299998223302991267312103414276992963861911174853919055822470048763842269788306246988883221693259159049588694161190408677435945636"}, + 41: {"-100", "1", "-1.560796660108231381024981575430471893537215347143176270859532877957451649939045719334570767484384443574366061972565500368626068848454065791553713241564500301545985135196418856718345713757628924143494438721608047007178718527060232023744938574481833397912364009735237313038166178173143279537136627742826361548235284750352378044025977820371529362683134445031777479652157848191657870077502388383723331123139111702281893170788430751754907735478382271641864205429133785178558795881284854174307762596466668129922037613487147557721948913501048415773028568729401122913139485533613408803919621823252100667169563997472137800355901284244384965079849712693552133035751044605646075445626682013404117070215091999781646367597573057819209803984748055256425128874674285411530539534963728145509712091667740997024765703103732001854246789690581692177245975297965997120707938361216091715901410828242694640618832406496038862320334997082410831649103052659997369163893970982656783920515684968957130015322434411503638848784976"}, + 42: {"100", "1", "1.560796660108231381024981575430471893537215347143176270859532877957451649939045719334570767484384443574366061972565500368626068848454065791553713241564500301545985135196418856718345713757628924143494438721608047007178718527060232023744938574481833397912364009735237313038166178173143279537136627742826361548235284750352378044025977820371529362683134445031777479652157848191657870077502388383723331123139111702281893170788430751754907735478382271641864205429133785178558795881284854174307762596466668129922037613487147557721948913501048415773028568729401122913139485533613408803919621823252100667169563997472137800355901284244384965079849712693552133035751044605646075445626682013404117070215091999781646367597573057819209803984748055256425128874674285411530539534963728145509712091667740997024765703103732001854246789690581692177245975297965997120707938361216091715901410828242694640618832406496038862320334997082410831649103052659997369163893970982656783920515684968957130015322434411503638848784976"}, + 43: {"1", "-100", "3.131592986903128000256303267070223335635800046830729181347005174111359853082150218648588180155442977565440105229206653692172991153229356907416392945628740860271127186547388117271125536069103401608685420936013534840145441591298056140638330157117434352485188293196967487343393341497249976340766752313463223841738587908146465484786438301786156408540816628978072659657823113466068103338194461859694086927855640337464772966764976844813598701784278824201138242660323766553342471824161216619921731687972642694838874294707475879264959610974246028141623919819331594764524755142201555392295814160661334501872129997756201372987681698137270636458744517280370722396485265056258552160699956806089642466354936629243417377575629122330190236001957135163240016260329265670884145209963727331998737067197606863432813862401244231581920243841902953331372647640483628086302023866217660635277854122009298831329140995330612514119461742296788566014682834091938546057690846961547712810781770582360436516286372717101593456995076"}, + 44: {"1", "100", "0.009999666686665238206340116209279548561369352544376639627939418196456553204058779979446645186674090416707981284075652954920853456321225324308966462499740257179156916154550403834434108553845553321696543492797440825788004537177592093148453008153767556660460273726492861267060985150963417266493496827810500745268018407441709396734482661043097683174547738914517700353507417082752363183189685092247424681577416932900986625188115341303783230827514280917409831802056196196224880061591508271306206495039306434994799067733180763821061783972149196595566782360529348938245784074974737784456570514157133167533002002811925772275879129648500706299045091893266456324983175844966401269446592779281408325924752629680124642380483006691770628032461024650389758510980694847823066140036271040979312883862124869383282456193780227873426664460739568976880697044551633844886147143785477203475032465523909550091476182338534789478791748131966902716476728771943807729902904996234144969750400644446176485641503894094315759425123245"}, + 45: {"-1", "100", "-0.009999666686665238206340116209279548561369352544376639627939418196456553204058779979446645186674090416707981284075652954920853456321225324308966462499740257179156916154550403834434108553845553321696543492797440825788004537177592093148453008153767556660460273726492861267060985150963417266493496827810500745268018407441709396734482661043097683174547738914517700353507417082752363183189685092247424681577416932900986625188115341303783230827514280917409831802056196196224880061591508271306206495039306434994799067733180763821061783972149196595566782360529348938245784074974737784456570514157133167533002002811925772275879129648500706299045091893266456324983175844966401269446592779281408325924752629680124642380483006691770628032461024650389758510980694847823066140036271040979312883862124869383282456193780227873426664460739568976880697044551633844886147143785477203475032465523909550091476182338534789478791748131966902716476728771943807729902904996234144969750400644446176485641503894094315759425123245"}, + 46: {"-1", "-100", "-3.131592986903128000256303267070223335635800046830729181347005174111359853082150218648588180155442977565440105229206653692172991153229356907416392945628740860271127186547388117271125536069103401608685420936013534840145441591298056140638330157117434352485188293196967487343393341497249976340766752313463223841738587908146465484786438301786156408540816628978072659657823113466068103338194461859694086927855640337464772966764976844813598701784278824201138242660323766553342471824161216619921731687972642694838874294707475879264959610974246028141623919819331594764524755142201555392295814160661334501872129997756201372987681698137270636458744517280370722396485265056258552160699956806089642466354936629243417377575629122330190236001957135163240016260329265670884145209963727331998737067197606863432813862401244231581920243841902953331372647640483628086302023866217660635277854122009298831329140995330612514119461742296788566014682834091938546057690846961547712810781770582360436516286372717101593456995076"}, + 47: {"-100", "-100", "-2.356194490192344928846982537459627163147877049531329365731208444230862304714656748971026119006587800986611064884961729985320383457162936673794019556096360838087713077026453890829169733467211716197786473321608231749450084596356736175340087373953401431859236425192595261457840744986160045205445186855955293440254954736691131161140690722121940568786523275919442770008497897911615349891038110213956133707074792952774319693964819139588036449458844828838911055846784972062175513914314543668420953637258961847375255021830492482314516046209796418552893026634895707777077904412882219882564288506113850752053849000426095358947670620839328507068342206880227884041101330675918715072609912189028288094209766944192656514967084096766470648025813619860222331078482470389030408512499998779733537463294798799612072238946268344591510181226981891731190008513776446448391128257502353379064664940649906286065462883251860477698690117821566601548369672147911765340695313968336393335399128420104959751445907458396931912315149"}, + 48: {"100", "100", "0.7853981633974483096156608458198757210492923498437764552437361480769541015715522496570087063355292669955370216283205766617734611523876455579313398520321202793625710256754846302763899111557372387325954911072027439164833615321189120584466957913178004772864121417308650871526135816620533484018150622853184311467516515788970437203802302407073135229288410919731475900028326326372051166303460367379853779023582643175914398979882730465293454831529482762796370186155949906873918379714381812228069845457529872824584183406101641607715053487365988061842976755449652359256926348042940732941880961687046169173512830001420317863158902069464428356894474022934092946803671102253062383575366373963427626980699223147308855049890280322554902160086045399534074436928274901296768028374999995932445124877649329332040240796487561148638367270756606305770633361712588154827970427525007844596882216468833020953551542944172868258995633726071888671827898907159705884468984379894454644451330428067016532504819691527989773041050497"}, } { t.Run(strconv.Itoa(i), func(t *testing.T) { z := decimal.WithPrecision(N)