Ancient

 view release on metacpan or  search on metacpan

t/9100-bigmath-quadmath.t  view on Meta::CPAN

    ok($retrieved == $quad_precise, 'slot stores quad precision value');

    # Test arithmetic preservation
    quad_sum(0);
    for (1..100) {
        quad_sum(quad_sum() + 0.01);
    }
    # With double precision, 0.01 * 100 often != 1.0 due to rounding
    # With quadmath, we get much better precision
    my $sum = quad_sum();
    ok(abs($sum - 1.0) < 1e-30, "slot arithmetic precision: got $sum");
}

# Test util numeric functions with quad precision
{
    require util;
    util->import(qw(is_num is_positive is_negative is_zero is_between clamp min2 max2 sign));

    my $result;

    $result = is_num($quad_precise);
    ok($result, 'is_num recognizes quad precision');

    $result = is_positive($quad_precise);
    ok($result, 'is_positive works with quad');

    $result = is_negative(-$quad_precise);
    ok($result, 'is_negative works with quad');

    my $tiny = 1e-4000;  # Only possible with quadmath
    $result = is_positive($tiny);
    ok($result, 'is_positive with very small quad value');

    $result = is_zero($tiny);
    ok(!$result, 'is_zero correctly identifies non-zero tiny quad');

    # Test with very large numbers (beyond double range)
    my $huge = 1e4000;
    $result = is_num($huge);
    ok($result, 'is_num with huge quad value');

    $result = is_positive($huge);
    ok($result, 'is_positive with huge quad value');

    # is_between with quad precision bounds
    $result = is_between($quad_precise, 1.0, 2.0);
    ok($result, 'is_between with quad precision');

    $result = is_between($quad_precise, 1.234567890123456, 1.234567890123457);
    ok($result, 'is_between with tight quad bounds');

    # clamp with quad precision
    my $clamped = clamp($quad_precise, 1.0, 1.2);
    is($clamped, 1.2, 'clamp respects quad precision upper bound');

    $clamped = clamp($quad_precise, 1.3, 2.0);
    is($clamped, 1.3, 'clamp respects quad precision lower bound');

    # min2/max2 with quad precision
    my $a = 1.23456789012345678901234567890123;
    my $b = 1.23456789012345678901234567890124;  # Differs in last digit

    my $min = min2($a, $b);
    my $max = max2($a, $b);
    ok($min == $a, 'min2 distinguishes quad precision values');
    ok($max == $b, 'max2 distinguishes quad precision values');

    # sign with quad precision
    is(sign($quad_precise), 1, 'sign positive quad');
    is(sign(-$quad_precise), -1, 'sign negative quad');
    is(sign(0.0), 0, 'sign zero');
}

# Test const with quad precision
{
    require const;

    # Test c() with hashref containing quad precision
    my $ref = const::c({ quad => $quad_precise });
    ok($ref->{quad} == $quad_precise, 'const c() preserves quad precision in hashref');

    eval { $ref->{quad} = 42 };
    ok($@, 'const hashref is readonly');

    # Test c() preserves quad precision (using scalar ref)
    my $pi_quad = 3.14159265358979323846264338327950288;
    my $pi_ref = const::c(\$pi_quad);
    ok($$pi_ref > 3.141592653589793, 'const stores more precision than double');
}

# Test heap with quad precision values
{
    require heap;

    # Create min heap with quad precision values
    my $h = heap::new('min');

    # Add values that differ only in quad precision range
    my @vals = (
        1.23456789012345678901234567890123,
        1.23456789012345678901234567890124,
        1.23456789012345678901234567890122,
        1.23456789012345678901234567890125,
        1.23456789012345678901234567890121,
    );

    $h->push($_) for @vals;

    my @sorted;
    push @sorted, $h->pop while $h->size > 0;

    # Verify sorted order (ascending for min heap)
    my $is_sorted = 1;
    for my $i (1 .. $#sorted) {
        if ($sorted[$i] < $sorted[$i-1]) {
            $is_sorted = 0;
            last;
        }
    }
    ok($is_sorted, 'heap sorts quad precision values correctly');

    # Verify the minimum was actually the smallest
    is($sorted[0], $vals[4], 'heap min is correct quad value');
}

# Test lru with quad precision keys and values
{
    require lru;

    my $cache = lru::new(10);

    # Use quad precision as values
    $cache->set('pi', 3.14159265358979323846264338327950288);
    $cache->set('e', 2.71828182845904523536028747135266250);

    my $pi = $cache->get('pi');
    my $e = $cache->get('e');

    ok($pi > 3.141592653589793, 'lru stores quad precision pi');
    ok($e > 2.718281828459045, 'lru stores quad precision e');

    # Test with stringified quad as key
    my $key = "$quad_precise";
    $cache->set($key, 'value');
    is($cache->get($key), 'value', 'lru works with quad precision string key');
}

# Test doubly with quad precision data
{
    require doubly;

    my $list = doubly->new($quad_precise);
    $list = $list->add(2 * $quad_precise);
    $list = $list->add(3 * $quad_precise);

    $list = $list->start;
    is($list->data, $quad_precise, 'doubly stores quad precision');

    $list = $list->next;
    ok(abs($list->data - 2 * $quad_precise) < 1e-30, 'doubly next quad precision');
}



( run in 1.035 second using v1.01-cache-2.11-cpan-df04353d9ac )