### ----------------------------------------------------
### -- BigRoot
### -- Licenses: Artistic-2.0
### -- Authors: Julio
### -- File: t/02-basic-tests.t
### ----------------------------------------------------
use BigRoot;
use Test;

# All results are checked with Wolfram Mathematica
# https://www.wolfram.com/mathematica/

plan 3;
subtest 'Tests using sqrt' => {
    plan 6;

    is BigRoot.newton's-sqrt(2), BigRoot.newton's-root(root => 2, number => 2), 'Both methods for sqrt(2) are equal';

    subtest 'Check sqrt of 1' => {
        plan 5;
        test-sqrt precision => 1, number => 1, expected => 1;
        test-sqrt precision => 10, number => 1, expected => 1.0000;
        test-sqrt precision => 100, number => 1, expected => 1;
        test-sqrt precision => 1000, number => 1, expected => 1;
        test-sqrt precision => 10_000, number => 1, expected => 1;
    }

    subtest 'Check sqrt of 0' => {
        plan 2;
        test-sqrt precision => 100, number => 0, expected => 0;
        test-sqrt precision => 1000, number => 0.00, expected => 0.0000;
    }

    subtest 'Square root of big numbers' => {
        plan 3;
        test-sqrt precision => 20, number => 999_999_999_999, expected => '999999.99999949999999999987';
        test-sqrt precision => 25, number => 888_999_777_666, expected => '942867.8474028054372914403664507';
        test-sqrt
                precision => 60,
                number => 999_888_777_666_555_444_333_222_111,
                expected => '31621017973280.927318964134330930188227996655971915399349639876798419597589';
    }

    subtest 'Rounds digits' => {
        plan 2;
        test-sqrt precision => 22, number => 999_999_999, expected => '31622.7765858724050151941917';
        test-sqrt precision => 21, number => 999_999_999, expected => '31622.776585872405015194192';
    }

    subtest 'Works with Str and FatRat' => {
        plan 2;
        test-sqrt
                precision => 70,
                number => 123_456_789,
                expected => '11111.1110605555554405416661433534692458784098601343510714585706752514714795';

        my $result = FatRat.new(111111110605555554405416661433534692458784098601343510714585706752514714795, 10 ** 70);
        test-sqrt precision => 70, number => 123_456_789, expected => $result;
    }
}

subtest 'Tests using other roots' => {
    plan 6;

    test-root
            precision => 82,
            root => 3,
            number => 2,
            expected => '1.2599210498948731647672106072782283505702514647015079800819751121552996765139594837';

    test-root
            precision => 82,
            root => 4,
            number => 2,
            expected => '1.1892071150027210667174999705604759152929720924638174130190022247194666682269171599';

    test-root
            precision => 82,
            root => 5,
            number => 2,
            expected => '1.1486983549970350067986269467779275894438508890977975055137111184936032062535130568';

    test-root
            precision => 30,
            root => 200,
            number => 2,
            expected => '1.00347174850950278700477431087';
    test-root
            precision => 30,
            root => 200,
            number => 123_456_789_123_456_789_000,
            expected => '1.260252521050578688716579247455';

    test-root
            precision => 1994,
            root => 3,
            number => 2,
            expected => '1.2599210498948731647672106072782283505702514647015079800819751121552996'
                    ~ '76513959483729396562436255094154310256035615665259399024040613737228459110'
                    ~ '30426935524696064261662500097747452656548030686718540551868924587251676419'
                    ~ '93737096950983827831613991551293136953661839474634485765703031190958959847'
                    ~ '41105981162907053590816478011473521325484771297880242208582053257972526662'
                    ~ '20266900566560819947156281764050606648267735726704194862076214429656942050'
                    ~ '79319172441480920448232840127470321964282081201905714188996459998317503801'
                    ~ '88868959420205592202115472997384880260736369741788779215798467509953963007'
                    ~ '82609596242034832386601398573634339097371265279959919699683779131681681544'
                    ~ '28850279651529278107679714002040605674803938561251718357006907984996341976'
                    ~ '29147404483454026971547622851317802064387804764932257905289846708580528625'
                    ~ '81300054293885607206097472230406313572349364584065759169169167270601244028'
                    ~ '96700001069081035313852902700415084232336239889386496782194149838027072957'
                    ~ '17681287900144574622714770234835715190550672208481848500928723920928264660'
                    ~ '67171742477537097370300127429180940544256965920750363575703751896037074739'
                    ~ '93461014490145157635960471111973845299132965726258904860978856180138677383'
                    ~ '61577300986598366080597575601278712148685624268455641165155817935322801589'
                    ~ '62912994450040120842541416015752584162988142309735821530604057724253836453'
                    ~ '25335659551172522855795622772403665628468759015430667535190854845118181752'
                    ~ '04291241233780963172521357541141811466127366045783036057440265130960709681'
                    ~ '64006888185657231009008428452608641405950336900307918699355691335183428569'
                    ~ '38262554313558973544502333028531493224551341219554578211965008339577142668'
                    ~ '50633284196196865121092557895588508996861901546700438968786655453098545057'
                    ~ '63765036008943306510356935777537249548436821370317162162183495809356208726'
                    ~ '00962678518341834565223974454000447602177889420818380278666530653266326186'
                    ~ '41160074007474754735585277016895020637541322323296942437017423434916176906'
                    ~ '00723853902227681129777413872079823430391031628546452083111122546828353183';
}

subtest 'Tests using Nums' => {
    plan 2;

    test-root
            precision => 80,
            root => 2,
            number => 5.55555555,
            expected => '2.35702260277664711239727417403971414610175097949487567155822146157444165276626569';

    test-root
            precision => 80,
            root => 5,
            number => 999.123456789123456789,
            expected => '3.9803735444295896667416659521492106573379085228872644298410580957156237436371309';
}

sub test-sqrt(:$precision, :$number, :$expected) {
    BigRoot.precision = $precision;
    my $result = BigRoot.newton's-sqrt($number);
    is $result, $expected, "square-root of { $number } - precision { BigRoot.precision }";
}

sub test-root(:$precision, :$root, :$number, :$expected) {
    BigRoot.precision = $precision;
    my $result = BigRoot.newton's-root(:$root, :$number);
    is $result, $expected, "{ $root }-root of { $number } - precision { BigRoot.precision }";
}

done-testing;


