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;