Acme-ExtUtils-XSOne-Test-Calculator

 view release on metacpan or  search on metacpan

Calculator.xs  view on Meta::CPAN

    /* Normalize angle to [-PI, PI] */
    while (radians > M_PI) radians -= 2.0 * M_PI;
    while (radians < -M_PI) radians += 2.0 * M_PI;
    return radians;
}

static int trig_is_valid_asin_arg(double x) {
    return (x >= -1.0 && x <= 1.0);
}

static double trig_sec(double x) {
    return 1.0 / cos(x);
}

static double trig_csc(double x) {
    return 1.0 / sin(x);
}

static double trig_cot(double x) {
    return cos(x) / sin(x);
}
/* C code from: _footer.xs */
#line 1 "lib/Acme/ExtUtils/XSOne/Test/_footer.xs"
/*
 * Acme::ExtUtils::XSOne::Test::Calculator - Main module and BOOT section
 */
/* ========== END COMBINED C PREAMBLE ========== */

MODULE = Acme::ExtUtils::XSOne::Test::Calculator    PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator::Basic

PROTOTYPES: DISABLE

double
add(a, b)
    double a

Calculator.xs  view on Meta::CPAN


double
normalize_angle(radians)
    double radians
CODE:
    RETVAL = trig_normalize_angle(radians);
OUTPUT:
    RETVAL

double
sec_val(a)
    double a
CODE:
    RETVAL = trig_sec(a);
    add_to_history('E', a, 0, RETVAL);
OUTPUT:
    RETVAL

double
csc_val(a)
    double a
CODE:
    RETVAL = trig_csc(a);
    add_to_history('O', a, 0, RETVAL);

Calculator.xs  view on Meta::CPAN

    RETVAL

void
import(...)
CODE:
{
    static const char *trig_exports[] = {
        "sin_val", "cos_val", "tan_val",
        "asin_val", "acos_val", "atan_val", "atan2_val",
        "deg_to_rad", "rad_to_deg", "hypot_val",
        "normalize_angle", "sec_val", "csc_val", "cot_val",
        "is_valid_asin_arg"
    };
    do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Trig",
              trig_exports, 15, items, ax);
}


MODULE = Acme::ExtUtils::XSOne::Test::Calculator    PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator

PROTOTYPES: DISABLE

lib/Acme/ExtUtils/XSOne/Test/Calculator.pm  view on Meta::CPAN

=item * L<Acme::ExtUtils::XSOne::Test::Calculator::Scientific>

Scientific operations: C<power>, C<sqrt_val>, C<cbrt_val>, C<nth_root>,
C<log_natural>, C<log10_val>, C<log_base>, C<exp_val>, C<factorial>,
C<ipow>, C<safe_sqrt>, C<safe_log>, C<combination>, C<permutation>

=item * L<Acme::ExtUtils::XSOne::Test::Calculator::Trig>

Trigonometry: C<sin_val>, C<cos_val>, C<tan_val>, C<asin_val>, C<acos_val>,
C<atan_val>, C<atan2_val>, C<deg_to_rad>, C<rad_to_deg>, C<hypot_val>,
C<normalize_angle>, C<sec_val>, C<csc_val>, C<cot_val>, C<is_valid_asin_arg>

=item * L<Acme::ExtUtils::XSOne::Test::Calculator::Memory>

Memory and history: C<store>, C<recall>, C<clear>, C<ans>, C<history_count>,
C<get_history_entry>, C<max_memory_slots>, C<max_history_entries>,
C<is_valid_slot>, C<used_slots>, C<sum_all_slots>, C<add_to>

=back

=head1 SHARED STATE

lib/Acme/ExtUtils/XSOne/Test/Calculator/Trig.pm  view on Meta::CPAN


    my $tan = Acme::ExtUtils::XSOne::Test::Calculator::Trig::tan_val(0.785398);   # ~1.0
    my $deg = Acme::ExtUtils::XSOne::Test::Calculator::Trig::rad_to_deg(3.14159); # ~180

=head1 EXPORTABLE FUNCTIONS

All functions can be imported by name:

    sin_val cos_val tan_val asin_val acos_val atan_val atan2_val
    deg_to_rad rad_to_deg hypot_val normalize_angle
    sec_val csc_val cot_val is_valid_asin_arg

=head1 DESCRIPTION

This module provides trigonometric functions as part of the
L<Acme::ExtUtils::XSOne::Test::Calculator> distribution. All angles are
in radians unless otherwise noted. Operations record their results
in the shared calculation history.

=head1 FUNCTIONS

lib/Acme/ExtUtils/XSOne/Test/Calculator/Trig.pm  view on Meta::CPAN


Returns the hypotenuse of a right triangle with sides C<$a> and C<$b>
(i.e., C<sqrt($a*$a + $b*$b)>).

=head2 normalize_angle

    my $result = normalize_angle($radians);

Normalizes an angle to the range C<[-PI, PI]>.

=head2 sec_val

    my $result = sec_val($radians);

Returns the secant of C<$radians> (i.e., C<1/cos($radians)>).

=head2 csc_val

    my $result = csc_val($radians);

Returns the cosecant of C<$radians> (i.e., C<1/sin($radians)>).

=head2 cot_val

    my $result = cot_val($radians);

Returns the cotangent of C<$radians> (i.e., C<cos($radians)/sin($radians)>).

=head2 is_valid_asin_arg

    my $bool = is_valid_asin_arg($x);

lib/Acme/ExtUtils/XSOne/Test/Calculator/Trig.xs  view on Meta::CPAN

    /* Normalize angle to [-PI, PI] */
    while (radians > M_PI) radians -= 2.0 * M_PI;
    while (radians < -M_PI) radians += 2.0 * M_PI;
    return radians;
}

static int trig_is_valid_asin_arg(double x) {
    return (x >= -1.0 && x <= 1.0);
}

static double trig_sec(double x) {
    return 1.0 / cos(x);
}

static double trig_csc(double x) {
    return 1.0 / sin(x);
}

static double trig_cot(double x) {
    return cos(x) / sin(x);
}

lib/Acme/ExtUtils/XSOne/Test/Calculator/Trig.xs  view on Meta::CPAN


double
normalize_angle(radians)
    double radians
CODE:
    RETVAL = trig_normalize_angle(radians);
OUTPUT:
    RETVAL

double
sec_val(a)
    double a
CODE:
    RETVAL = trig_sec(a);
    add_to_history('E', a, 0, RETVAL);
OUTPUT:
    RETVAL

double
csc_val(a)
    double a
CODE:
    RETVAL = trig_csc(a);
    add_to_history('O', a, 0, RETVAL);

lib/Acme/ExtUtils/XSOne/Test/Calculator/Trig.xs  view on Meta::CPAN

    RETVAL

void
import(...)
CODE:
{
    static const char *trig_exports[] = {
        "sin_val", "cos_val", "tan_val",
        "asin_val", "acos_val", "atan_val", "atan2_val",
        "deg_to_rad", "rad_to_deg", "hypot_val",
        "normalize_angle", "sec_val", "csc_val", "cot_val",
        "is_valid_asin_arg"
    };
    do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Trig",
              trig_exports, 15, items, ax);
}

lib/Acme/ExtUtils/XSOne/Test/_footer.xs  view on Meta::CPAN

/*
 * Acme::ExtUtils::XSOne::Test::Calculator - Main module and BOOT section
 */

MODULE = Acme::ExtUtils::XSOne::Test::Calculator    PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator

PROTOTYPES: DISABLE

double
pi()
CODE:
    RETVAL = M_PI;

t/01-calculator.t  view on Meta::CPAN

    ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::tan_val(0)) < 0.0001, 'tan(0) = 0');

    is(Acme::ExtUtils::XSOne::Test::Calculator::Trig::hypot_val(3, 4), 5, 'hypot(3, 4) = 5');

    ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::deg_to_rad(180) - $pi) < 0.0001, 'deg_to_rad(180) = pi');

    # Test C helper functions (defined in trig.xs preamble)
    ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::normalize_angle(3 * $pi) - $pi) < 0.0001, 'normalize_angle(3*pi) = pi');
    ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::normalize_angle(-3 * $pi) - (-$pi)) < 0.0001, 'normalize_angle(-3*pi) = -pi');

    ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::sec_val(0) - 1) < 0.0001, 'sec(0) = 1');
    ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::csc_val($pi/2) - 1) < 0.0001, 'csc(pi/2) = 1');
    ok(abs(Acme::ExtUtils::XSOne::Test::Calculator::Trig::cot_val($pi/4) - 1) < 0.0001, 'cot(pi/4) = 1');

    is(Acme::ExtUtils::XSOne::Test::Calculator::Trig::is_valid_asin_arg(0.5), 1, 'is_valid_asin_arg(0.5) = 1');
    is(Acme::ExtUtils::XSOne::Test::Calculator::Trig::is_valid_asin_arg(2.0), 0, 'is_valid_asin_arg(2.0) = 0');
};

subtest 'Inverse trig' => sub {
    plan tests => 3;

t/02-import.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;

# =============================================================================
# Test importing functions from each submodule
# =============================================================================

use_ok('Acme::ExtUtils::XSOne::Test::Calculator::Basic', qw(add subtract multiply divide modulo negate absolute safe_divide clamp percent));
use_ok('Acme::ExtUtils::XSOne::Test::Calculator::Scientific', qw(power sqrt_val cbrt_val nth_root log_natural log10_val log_base exp_val factorial ipow safe_sqrt safe_log combination permutation));
use_ok('Acme::ExtUtils::XSOne::Test::Calculator::Trig', qw(sin_val cos_val tan_val asin_val acos_val atan_val atan2_val deg_to_rad rad_to_deg hypot_val normalize_angle sec_val csc_val cot_val is_valid_asin_arg));
use_ok('Acme::ExtUtils::XSOne::Test::Calculator::Memory', qw(store recall clear ans history_count get_history_entry max_memory_slots max_history_entries is_valid_slot used_slots sum_all_slots add_to));

# Also load the main module for constants
use Acme::ExtUtils::XSOne::Test::Calculator;

# =============================================================================
# Test constants (using fully qualified - not exported)
# =============================================================================

subtest 'Constants' => sub {

t/02-import.t  view on Meta::CPAN


    ok(abs(tan_val(0)) < 0.0001, 'tan(0) = 0');

    is(hypot_val(3, 4), 5, 'hypot(3, 4) = 5');

    ok(abs(deg_to_rad(180) - $pi) < 0.0001, 'deg_to_rad(180) = pi');

    ok(abs(normalize_angle(3 * $pi) - $pi) < 0.0001, 'normalize_angle(3*pi) = pi');
    ok(abs(normalize_angle(-3 * $pi) - (-$pi)) < 0.0001, 'normalize_angle(-3*pi) = -pi');

    ok(abs(sec_val(0) - 1) < 0.0001, 'sec(0) = 1');
    ok(abs(csc_val($pi/2) - 1) < 0.0001, 'csc(pi/2) = 1');
    ok(abs(cot_val($pi/4) - 1) < 0.0001, 'cot(pi/4) = 1');

    is(is_valid_asin_arg(0.5), 1, 'is_valid_asin_arg(0.5) = 1');
    is(is_valid_asin_arg(2.0), 0, 'is_valid_asin_arg(2.0) = 0');
};

subtest 'Inverse trig' => sub {
    plan tests => 3;



( run in 1.232 second using v1.01-cache-2.11-cpan-39bf76dae61 )