Trigonometric functions: Difference between revisions

→‎{{header|REXX}}: reduced decimal digits precision, add/changed statments, comments, and whitespace, used a template for the output section.
m (→‎{{header|REBOL}}: Remove vanity tags)
(→‎{{header|REXX}}: reduced decimal digits precision, add/changed statments, comments, and whitespace, used a template for the output section.)
Line 3,960:
functions are wanted, you have to roll your own.
Some of the normal/regular trigonometric functions are included here.
<lang rexx> ┌──────────────────────────────────────────────────────────────────────────┐
│ One common method that ensures enough accuracy in REXX is specifying │
│ more precision (via NUMERIC DIGITS nnn) than is needed, and then │
│ displaying the number of digits that are desired, or the number(s) │
│ could be re-normalized using the FORMAT BIF. │
│ │
│ The technique used (below) is to set the numeric digits ten higher │
│ than the desired digits, as specified by the SHOWDIGS variable. │
└──────────────────────────────────────────────────────────────────────────┘</lang>
Most math (POW, EXP, LOG, LN, GAMMA, etc.), trigonometric, and hyperbolic functions need only five extra digits, but ten
<br>extra digits is safer in case the argument is close to an asymptotic point or a multiple or fractional part of pi or somesuch.
Line 3,976:
<br>extended digits for '''pi''' or '''e''', I could extend them to any almost any precision (as a REXX constant). &nbsp; Normally, a REXX
<br>(external) subroutine is used for such purposes so as to not make the program using the constant unwieldy large.
<lang rexx>/*REXX program demonstrates some common trig functions (30 decimal digits are shown).*/
showdigs=30 25 /*show only 3025 digits of number. */
numeric digits showdigs + 10 /*DIGITS default is 9, but use */
/*extra digs to prevent rounding.*/
say 'Using' showdigs 'decimal digits precision.' /*show # decimal digs being used.*/
 
say
say 'Using' showdigs 'decimal digits precision.'; say
do j=-180 to +180 by 15 /*let's just do a half─Monty. */
 
do j=-180 tostuff +180= right(j, by4) 15 'degrees, /*letrads='s just do a half-Monty.show( d2r(j) ) */,
stuff = right(j,4) 'degrees, rads sin=' show( d2rsinD(j) ) ,
' sincos=' show(sinD cosD(jJ) ),
' cos= /*don'show(cosD(J))t let TANGENT go postal. */
if abs(j)\==90 then stuff=stuff ' tan=' show( tanD(j) )
/*don't let TAN go postal.*/
say stuff
if abs(j)\==90 then stuff=stuff ' tan='show(tanD(j))
end /*j*/
say stuff
say
end /*j*/
do k=-1 to +1 by 1/2 /*keep the Arc─functions happy. */
 
say; right(k, 4) do k=-1 to +1 by 1/2 'radians, degs=' show( r2d(k) ) /*keep the Arc-functions happy. */,
say right(k,4) 'radians, degs Acos=' show( r2dAcos(k) ) ,
' AcosAsin=' show(Acos Asin(k) ) ,
' AsinAtan=' show(Asin Atan(k) ),
end /*k*/
' Atan='show(Atan(k))
exit /*stick a fork in it, we're done.*/
end /*k*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────subroutines─────────────────────────*/
Asin: procedure; parse arg x 1 z 1 o 1 p; a=abs(x); aa=a*a
if a>1 then call AsinErr x /*X argargument is out of range. */
if a >= sqrt(2) * .5 then return sign(x) * acos( sqrt(1 - aa), '-ASIN')
do j=2 by 2 until p=z; p=z; o= o * aa * (j-1) / j; z= z +o / (j+1); end
return z /* [↑] compute until no noise. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
 
AtanAcos: procedure; parse arg x; if abs(x)=<-1 | x>1 then call AcosErr; return pi() * .255 *- signAsin(x)
AcosD: return r2d( Acos( arg(1) ) )
return Asin(x/sqrt(1+x*x) )
AsinD: return r2d( Asin( arg(1) ) )
 
coscosD: procedure;return parsecos( argd2r( x; x=r2rarg(x1); a=abs(x); hpi=pi*.5)
sinD: return sin( d2r( d2d( arg(1) ) ) )
numeric fuzz min(6,digits()-3); if a=pi() then return -1
tan: procedure; parse arg x; _= cos(x); if a=hpi | aif _=hpi*30 then returncall 0tanErr; return if a=pisin(x) /3 then return .5_
tanD: return tan( d2r( arg(1) ) )
if a=pi()*2/3 then return -.5; return .sinCos(1,-1)
d2d: return arg(1) // 360 /*normalize degrees ──► a unit circle*/
 
sind2r: return procedure;r2r( parsed2d( arg(1) x;)*pi() / x=r2r(x 180); /*convert numeric fuzz $fuzz(5,degrees 3)──► radians. */
r2d: return d2d( ( arg(1) * if180 x=pi*.5 then return 1; / pi() ) ) /*convert radians ──► degrees. if x==pi*1.5 then return -1/
r2r: return arg(1) // (pi() *2) /*normalize radians ──► a unit circle*/
if abs(x)=pi | x=0 then return 0; return .sinCos(x,1)
show: return left( left('', arg(1) >= 0)format( arg(1), , showdigs) / 1, showdigs)
 
.sinCos: parse arg z 1 _,i; q=x*x
do k=2 by 2 until p=z; p=z; _=-_*q/(k*(k+i)); z=z+_; end /*k*/
return z
 
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); i=; m.=9
numeric digits 9; numeric form; h=d+6; if x<0 then do; x=-x; i='i'; end
parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g*.5'e'_%2
do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/
numeric digits d; return (g/1)i /*make complex if X < 0.*/
 
 
e: e=2.7182818284590452353602874713526624977572470936999595749669676277240766303535
return e /*Note: the actual E subroutine returns E's accuracy that */
/*matches the current NUMERIC DIGITS, up to 1 million digits.*/
 
exp: procedure; parse arg x; ix=x%1; if abs(x-ix)>.5 then ix=ix+sign(x); x=x-ix
z=1; _=1; w=z; do j=1; _=_*x/j; z=(z+_)/1; if z==w then leave; w=z; end
if z\==0 then z=e()**ix*z; return z
 
pi: pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862
return pi /*Note: the actual PI subroutine returns PI's accuracy that */
/*matches the current NUMERIC DIGITS, up to 1 million digits.*/
/*John Machin's formula is used for calculating more digits. */
 
$fuzz: return min(arg(1), max(1, digits() - arg(2) ) )
Acos: procedure; parse arg x; if x<-1|x>1 then call AcosErr; return pi()*.5-Asin(x)
AcosD: return r2d(Acos(arg(1)))
AsinD: return r2d(Asin(arg(1)))
cosD: return cos(d2r(arg(1)))
sinD: return sin(d2r(d2d(arg(1))))
tan: procedure; parse arg x; _=cos(x); if _=0 then call tanErr; return sin(x)/_
tanD: return tan(d2r(arg(1)))
d2d: return arg(1) // 360 /*normalize degrees ──► a unit circle*/
d2r: return r2r(d2d(arg(1))*pi() / 180) /*convert degrees ──► radians. */
r2d: return d2d((arg(1)*180 / pi())) /*convert radians ──► degrees. */
r2r: return arg(1) // (pi()*2) /*normalize radians ──► a unit circle*/
show: return left(left('',arg(1)>=0)format(arg(1),,showdigs)/1,showdigs)
tellErr: say; say '*** error! ***'; say; say arg(1); say; exit 13
tanErr: call tellErr 'tan(' || x") causes division by zero, X=" || x
AsinErr: call tellErr 'Asin(x), X must be in the range of -1 ──► +1, X=' || x
AcosErr: call tellErr 'Acos(x), X must be in the range of -1 ──► +1, X=' || x</lang>
/*──────────────────────────────────────────────────────────────────────────────────────*/
Atan: procedure; parse arg x; if abs(x)=1 then return pi() * .25 * sign(x)
return Asin(x / sqrt(1 + x*x) )
/*──────────────────────────────────────────────────────────────────────────────────────*/
cos: procedure; parse arg x; x= r2r(x); a=abs(x); hpi= pi * .5
numeric fuzz min(6, digits() - 3); if a=pi() then return -1
if a=hpi | a=hpi*3 then return 0; if a=pi() / 3 then return .5
if a=pi() * 2 / 3 then return -.5; return .sinCos(1, -1)
/*──────────────────────────────────────────────────────────────────────────────────────*/
sin: procedure; parse arg x; x=r2r(x); numeric fuzz min(5, max(1, digits() -3))
if x=pi*.5 then return 1; if x==pi * 1.5 then return -1
if abs(x)=pi | x=0 then return 0; return .sinCos(x, 1)
/*──────────────────────────────────────────────────────────────────────────────────────*/
.sinCos: parse arg z 1 _,i; q= x*x
do k=2 by 2 until p=z; p= z; _= - _ * q / (k * (k+i) ); z= z+_; end
return z
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); i=; m.=9; h= d+6
numeric digits; numeric form; if x<0 then do; x= -x; i= 'i'; end
parse value format(x, 2, 1, , 0) 'E0' with g 'E' _ .; g= g *.5'e'_ % 2
do j=0 while h>9; m.j=h; h= h % 2 + 1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g= (g+x/g) * .5; end /*k*/
numeric digits d; return (g/1)i /*make complex if X < 0.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
e: e = 2.7182818284590452353602874713526624977572470936999595749669676277240766303535
return e /*Note: the actual E subroutine returns E's accuracy that */
/*matches the current NUMERIC DIGITS, up to 1 million digits.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
exp: procedure; parse arg x; ix=x%1; if abs(x-ix)>.5 then ix= ix + sign(x); x=x - ix
z=1; _=1; w=z; do j=1; _= _*x/j; z= (z+_) / 1; if z==w then leave; w=z; end
if z\==0 then z= e()**ix * z; return z
/*──────────────────────────────────────────────────────────────────────────────────────*/
pi: pi= 3.1415926535897932384626433832795028841971693993751058209749445923078164062862
return pi /*Note: the actual PI subroutine returns PI's accuracy that */
/*matches the current NUMERIC DIGITS, up to 1 million digits.*/
/*John Machin's formula is used for calculating more digits. */</lang>
Programming note:
<lang rexx> ╔═════════════════════════════════════════════════════════════════════════════╗
║ Functions that are not included here are (among others): ║
║ ║
║ some of the usual higher-math functions normally associated with trig ║
║ functions: POW, GAMMA, LGGAMMA, ERF, ERFC, ROOT, ATAN2, ║
║ LOG (LN), LOG2, LOG10, and all of the ║
║ hyperbolic trigonometric functions and their inverses (too many to list ║
║ here), ║
║ angle conversions/normalizations: degrees/radians/grads/mils: ║
║ a circle ≡ 2 pi radians ≡ 360 degrees ≡ 400 grads ≡ 6400 mils. ║
║ ║
║ Some of the other trigonometric functions are (hyphens added intentionally):║
║ ║
║ CHORD ║
║ COT (co-tangent) ║
║ CSC (co-secant) ║
║ CVC (co-versed cosine) ║
║ CVS (co-versed sine) ║
║ CXS (co-exsecant) ║
║ HAC (haver-cosine) ║
║ HAV (haver-sine ║
║ SEC (secant) ║
║ VCS (versed cosine or ver-cosine) ║
║ VSN (versed sine or ver-sine) ║
║ XCS (ex-secant) ║
║ COS/SIN/TAN cardinal (damped COS/SIN/TAN functions) ║
║ COS/SIN integral ║
║ ║
║ and all pertinent inverses of the above functions (AVSN, ACVS, ···). ║
╚═════════════════════════════════════════════════════════════════════════════╝</lang>
'''{{out|output'''}}
 
<pre>
(Shown at three-quarter size.)
Using 30 decimal digits precision.
<pre style="font-size:75%>
Using 25 decimal digits precision.
 
-180 degrees, rads= -3.1415926535897932384626433831415926535897932384626 sin= 0 cos= -1 tan= 0
-165 degrees, rads= -2.8797932657906438019240897688797932657906438019240 sin= -0.2588190451025207623488988372588190451025207623488 cos= -0.9659258262890682867497431999659258262890682867497 tan= 0.2679491924311227064725536582679491924311227064725
-150 degrees, rads= -2.6179938779914943653855361526179938779914943653855 sin= -0.5 cos= -0.8660254037844386467637231708660254037844386467637 tan= 0.5773502691896257645091487805773502691896257645091
-135 degrees, rads= -2.3561944901923449288469825373561944901923449288469 sin= -0.7071067811865475244008443627071067811865475244008 cos= -0.7071067811865475244008443627071067811865475244008 tan= 1
-120 degrees, rads= -2.0943951023931954923084289220943951023931954923084 sin= -0.8660254037844386467637231708660254037844386467637 cos= -0.5 tan= 1.7320508075688772935274463417320508075688772935274
-105 degrees, rads= -1.8325957145940460557698753068325957145940460557698 sin= -0.9659258262890682867497431999659258262890682867497 cos= -0.2588190451025207623488988372588190451025207623488 tan= 3.7320508075688772935274463417320508075688772935274
-90 degrees, rads= -1.5707963267948966192313216915707963267948966192313 sin= -1 cos= 0
-75 degrees, rads= -1.3089969389957471826927680763089969389957471826927 sin= -0.9659258262890682867497431999659258262890682867497 cos= 0.2588190451025207623488988372588190451025207623488 tan= -3.7320508075688772935274463417320508075688772935274
-60 degrees, rads= -1.0471975511965977461542144610471975511965977461542 sin= -0.8660254037844386467637231708660254037844386467637 cos= 0.5 tan= -1.7320508075688772935274463417320508075688772935274
-45 degrees, rads= -0.7853981633974483096156608457853981633974483096156 sin= -0.7071067811865475244008443627071067811865475244008 cos= 0.7071067811865475244008443627071067811865475244008 tan= -1
-30 degrees, rads= -0.5235987755982988730771072305235987755982988730771 sin= -0.5 cos= 0.8660254037844386467637231708660254037844386467637 tan= -0.5773502691896257645091487805773502691896257645091
-15 degrees, rads= -0.2617993877991494365385536152617993877991494365385 sin= -0.2588190451025207623488988372588190451025207623488 cos= 0.9659258262890682867497431999659258262890682867497 tan= -0.2679491924311227064725536582679491924311227064725
0 degrees, rads= 0 sin= 0 cos= 1 tan= 0
15 degrees, rads= 0.2617993877991494365385536152617993877991494365385 sin= 0.2588190451025207623488988372588190451025207623488 cos= 0.9659258262890682867497431999659258262890682867497 tan= 0.2679491924311227064725536582679491924311227064725
30 degrees, rads= 0.5235987755982988730771072305235987755982988730771 sin= 0.5 cos= 0.8660254037844386467637231708660254037844386467637 tan= 0.5773502691896257645091487805773502691896257645091
45 degrees, rads= 0.7853981633974483096156608457853981633974483096156 sin= 0.7071067811865475244008443627071067811865475244008 cos= 0.7071067811865475244008443627071067811865475244008 tan= 1
60 degrees, rads= 1.0471975511965977461542144610471975511965977461542 sin= 0.8660254037844386467637231708660254037844386467637 cos= 0.5 tan= 1.7320508075688772935274463417320508075688772935274
75 degrees, rads= 1.3089969389957471826927680763089969389957471826927 sin= 0.9659258262890682867497431999659258262890682867497 cos= 0.2588190451025207623488988372588190451025207623488 tan= 3.7320508075688772935274463417320508075688772935274
90 degrees, rads= 1.5707963267948966192313216915707963267948966192313 sin= 1 cos= 0
105 degrees, rads= 1.8325957145940460557698753068325957145940460557698 sin= 0.9659258262890682867497431999659258262890682867497 cos= -0.2588190451025207623488988372588190451025207623488 tan= -3.7320508075688772935274463417320508075688772935274
120 degrees, rads= 2.0943951023931954923084289220943951023931954923084 sin= 0.8660254037844386467637231708660254037844386467637 cos= -0.5 tan= -1.7320508075688772935274463417320508075688772935274
135 degrees, rads= 2.3561944901923449288469825373561944901923449288469 sin= 0.7071067811865475244008443627071067811865475244008 cos= -0.7071067811865475244008443627071067811865475244008 tan= -1
150 degrees, rads= 2.6179938779914943653855361526179938779914943653855 sin= 0.5 cos= -0.8660254037844386467637231708660254037844386467637 tan= -0.5773502691896257645091487805773502691896257645091
165 degrees, rads= 2.8797932657906438019240897688797932657906438019240 sin= 0.2588190451025207623488988372588190451025207623488 cos= -0.9659258262890682867497431999659258262890682867497 tan= -0.2679491924311227064725536582679491924311227064725
180 degrees, rads= 3.1415926535897932384626433831415926535897932384626 sin= 0 cos= -1 tan= 0
 
-1 radians, degs= -57.29577951308232087679815481295779513082320876798 Acos= 3.1415926535897932384626433831415926535897932384626 Asin= -1.5707963267948966192313216915707963267948966192313 Atan= -0.7853981633974483096156608457853981633974483096156
-0.5 radians, degs= -28.64788975654116043839907740647889756541160438399 Acos= 2.0943951023931954923084289220943951023931954923084 Asin= -0.5235987755982988730771072305235987755982988730771 Atan= -0.4636476090008061162142562314636476090008061162142
0 radians, degs= 0 Acos= 1.5707963267948966192313216915707963267948966192313 Asin= 0 Atan= 0
0.5 radians, degs= 28.64788975654116043839907740647889756541160438399 Acos= 1.0471975511965977461542144610471975511965977461542 Asin= 0.5235987755982988730771072305235987755982988730771 Atan= 0.4636476090008061162142562314636476090008061162142
1.0 radians, degs= 57.29577951308232087679815481295779513082320876798 Acos= 0 Asin= 1.5707963267948966192313216915707963267948966192313 Atan= 0.7853981633974483096156608457853981633974483096156
</pre>