This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Test relying on undefined behaviour of atan2(0, 0)
[perl5.git] / lib / Math / Trig.t
1 #!./perl 
2
3 #
4 # Regression tests for the Math::Trig package
5 #
6 # The tests are quite modest as the Math::Complex tests exercise
7 # these quite vigorously.
8
9 # -- Jarkko Hietaniemi, April 1997
10
11 BEGIN {
12     chdir 't' if -d 't';
13     @INC = '../lib';
14 }
15
16 use Math::Trig;
17
18 use strict;
19
20 use vars qw($x $y $z);
21
22 my $eps = 1e-11;
23
24 if ($^O eq 'unicos') { # See lib/Math/Complex.pm and t/lib/complex.t.
25     $eps = 1e-10;
26 }
27
28 sub near ($$;$) {
29     my $e = defined $_[2] ? $_[2] : $eps;
30     $_[1] ? (abs($_[0]/$_[1] - 1) < $e) : abs($_[0]) < $e;
31 }
32
33 print "1..26\n";
34
35 $x = 0.9;
36 print 'not ' unless (near(tan($x), sin($x) / cos($x)));
37 print "ok 1\n";
38
39 print 'not ' unless (near(sinh(2), 3.62686040784702));
40 print "ok 2\n";
41
42 print 'not ' unless (near(acsch(0.1), 2.99822295029797));
43 print "ok 3\n";
44
45 $x = asin(2);
46 print 'not ' unless (ref $x eq 'Math::Complex');
47 print "ok 4\n";
48
49 # avoid using Math::Complex here
50 $x =~ /^([^-]+)(-[^i]+)i$/;
51 ($y, $z) = ($1, $2);
52 print 'not ' unless (near($y,  1.5707963267949) and
53                      near($z, -1.31695789692482));
54 print "ok 5\n";
55
56 print 'not ' unless (near(deg2rad(90), pi/2));
57 print "ok 6\n";
58
59 print 'not ' unless (near(rad2deg(pi), 180));
60 print "ok 7\n";
61
62 use Math::Trig ':radial';
63
64 {
65     my ($r,$t,$z) = cartesian_to_cylindrical(1,1,1);
66
67     print 'not ' unless (near($r, sqrt(2)))     and
68                         (near($t, deg2rad(45))) and
69                         (near($z, 1));
70     print "ok 8\n";
71
72     ($x,$y,$z) = cylindrical_to_cartesian($r, $t, $z);
73
74     print 'not ' unless (near($x, 1)) and
75                         (near($y, 1)) and
76                         (near($z, 1));
77     print "ok 9\n";
78
79     ($r,$t,$z) = cartesian_to_cylindrical(1,1,0);
80
81     print 'not ' unless (near($r, sqrt(2)))     and
82                         (near($t, deg2rad(45))) and
83                         (near($z, 0));
84     print "ok 10\n";
85
86     ($x,$y,$z) = cylindrical_to_cartesian($r, $t, $z);
87
88     print 'not ' unless (near($x, 1)) and
89                         (near($y, 1)) and
90                         (near($z, 0));
91     print "ok 11\n";
92 }
93
94 {
95     my ($r,$t,$f) = cartesian_to_spherical(1,1,1);
96
97     print 'not ' unless (near($r, sqrt(3)))     and
98                         (near($t, deg2rad(45))) and
99                         (near($f, atan2(sqrt(2), 1)));
100     print "ok 12\n";
101
102     ($x,$y,$z) = spherical_to_cartesian($r, $t, $f);
103
104     print 'not ' unless (near($x, 1)) and
105                         (near($y, 1)) and
106                         (near($z, 1));
107     print "ok 13\n";
108
109     ($r,$t,$f) = cartesian_to_spherical(1,1,0);
110
111     print 'not ' unless (near($r, sqrt(2)))     and
112                         (near($t, deg2rad(45))) and
113                         (near($f, deg2rad(90)));
114     print "ok 14\n";
115
116     ($x,$y,$z) = spherical_to_cartesian($r, $t, $f);
117
118     print 'not ' unless (near($x, 1)) and
119                         (near($y, 1)) and
120                         (near($z, 0));
121     print "ok 15\n";
122 }
123
124 {
125     my ($r,$t,$z) = cylindrical_to_spherical(spherical_to_cylindrical(1,1,1));
126
127     print 'not ' unless (near($r, 1)) and
128                         (near($t, 1)) and
129                         (near($z, 1));
130     print "ok 16\n";
131
132     ($r,$t,$z) = spherical_to_cylindrical(cylindrical_to_spherical(1,1,1));
133
134     print 'not ' unless (near($r, 1)) and
135                         (near($t, 1)) and
136                         (near($z, 1));
137     print "ok 17\n";
138 }
139
140 {
141     use Math::Trig 'great_circle_distance';
142
143     print 'not '
144         unless (near(great_circle_distance(0, 0, 0, pi/2), pi/2));
145     print "ok 18\n";
146
147     print 'not '
148         unless (near(great_circle_distance(0, 0, pi, pi), pi));
149     print "ok 19\n";
150
151     # London to Tokyo.
152     my @L = (deg2rad(-0.5), deg2rad(90 - 51.3));
153     my @T = (deg2rad(139.8),deg2rad(90 - 35.7));
154
155     my $km = great_circle_distance(@L, @T, 6378);
156
157     print 'not ' unless (near($km, 9605.26637021388));
158     print "ok 20\n";
159 }
160
161 {
162     my $R2D = 57.295779513082320876798154814169;
163
164     sub frac { $_[0] - int($_[0]) }
165
166     my $lotta_radians = deg2rad(1E+20, 1);
167     print "not " unless near($lotta_radians,  1E+20/$R2D);
168     print "ok 21\n";
169
170     my $negat_degrees = rad2deg(-1E20, 1);
171     print "not " unless near($negat_degrees, -1E+20*$R2D);
172     print "ok 22\n";
173
174     my $posit_degrees = rad2deg(-10000, 1);
175     print "not " unless near($posit_degrees, -10000*$R2D);
176     print "ok 23\n";
177 }
178
179 {
180     use Math::Trig 'great_circle_direction';
181
182     print 'not '
183         unless (near(great_circle_direction(0, 0, 0, pi/2), pi));
184     print "ok 24\n";
185
186 # Retired test: Relies on atan(0, 0), which is not portable.
187 #    print 'not '
188 #       unless (near(great_circle_direction(0, 0, pi, pi), -pi()/2));
189     print "ok 25\n";
190
191     # London to Tokyo.
192     my @L = (deg2rad(-0.5), deg2rad(90 - 51.3));
193     my @T = (deg2rad(139.8),deg2rad(90 - 35.7));
194
195     my $rad = great_circle_direction(@L, @T);
196
197     print 'not ' unless (near($rad, -0.546644569997376));
198     print "ok 26\n";
199 }
200
201 # eof