05-28-2003, 10:27 AM
05-28-2003, 09:50 PM
Code:
DEFDBL A-Z 'Joe Campbell-2003
pi = 3.141592653589793#
CLS
DO
sinex = 0
sign% = 1
INPUT "Enter an angle(degree), I'll calculate it's Sine!", angledeg
a = angledeg
DO WHILE a >= 360 'force angle between -360 to 360 deg
a = a - 360
LOOP
DO WHILE a <= -360
a = a + 360
LOOP
angrad = a * (pi / 180) 'to radians
FOR x = 1 TO 31 STEP 2 '31 iterations is more than enough precision for 8 sig-figs
xfac = 1 'reset between visits...
FOR t = 1 TO x
xfac = t * xfac 'calculate x!
NEXT t
sinex = sinex + (sign% * ((angrad ^ x) / xfac)) 'Taylor series
sign% = sign% * -1 'toggle +/-
IF ABS(ABS(oldsine) - ABS(sinex)) < .0000000001# THEN EXIT FOR 'stop at 9 sig-figs
oldsine = sinex 'to compare to determine when to stop
NEXT x
PRINT "SIN("; angledeg;:PRINT USING ") = #.########"; sinex 'print 8 sig-figs
LOOP
END
05-29-2003, 12:28 AM
Code:
DEFDBL A-Z 'Joe Campbell-2003
COMMON SHARED sigfig
COMMON SHARED Pi
DECLARE FUNCTION sineIt# (deg#)
CLS
sigfig = 11 'Make this smaller for less precision
Pi = 3.141592653589793#
DO
INPUT "Enter an angle(degrees), I'll calculate it's Sine!", deg
PRINT
PRINT "SIN "; deg; " ="
PRINT USING "#.########"; sineIt(deg); : PRINT " rounded to 8 sig-figs"
PRINT sineIt(deg); " All available digits"
PRINT SIN(deg * Pi / 180); " QBasic SIN result"
PRINT
LOOP
END
FUNCTION sineIt (deg)
sign% = 1
sinex = 0
sign% = 1
a = deg
DO WHILE a >= 360 'force angle between -360 to 360 deg
a = a - 360
LOOP
DO WHILE a <= -360
a = a + 360
LOOP
angrad = a * (Pi / 180) 'to radians
FOR x = 1 TO 31 STEP 2 '31 iterations is more than enough precision for 8 sig-figs
xfac = 1
FOR t = 1 TO x
xfac = t * xfac 'calculate x!
NEXT t
sinex = sinex + (sign% * ((angrad ^ x) / xfac)) 'Taylor series
sign% = sign% * -1 'toggle +/-
IF ABS(ABS(oldsine) - ABS(sinex)) < 10 ^ (-1 * sigfig) THEN EXIT FOR 'stop series when required precision is attained
oldsine = sinex
NEXT x
sineIt = sinex
END FUNCTION
05-29-2003, 12:41 AM
y'know, i wonder if there's a way to do this without using a taylor series. i wish there was a formula like the pi one where you can extract the nth digit.
05-29-2003, 12:48 AM
Quote:y'know, i wonder if there's a way to do this without using a taylor series.
It can be done using the half angle formula. This way...starting with one you can figure out (ie sin 45=(2^0.5)/2 or 30=.5 or 60 = (3^.5)/2) you can calculate enough half angles and add them together to figure out the sin of an arbitrary angle.
However, the Taylor series seems a lot more straight forward.
05-29-2003, 01:03 AM
the Taylor series (or using trig formulas). Tell Oracle to send you the convoluted thing I emailed him. (And you'll be real sorry you asked that.)
05-30-2003, 03:34 AM
Heeh, I was just about to post with your method... :wink:
I have tested Mango's method. It's pretty good also, very accurate (you needn't have rounded it to 8sf, it works up to 11sf ok), and quite fast (unlike Glenn's one, eh Glenn :wink: ), but toonski already did the taylor series so he is still winning. I'll continue this contest for another 3 days so you guys have a chance of catching toonski.
Here's Glenn's method:
Careful of any line wrap... and it's the slowest possible way to calculate sine ever! Special award for Glenn!
I have tested Mango's method. It's pretty good also, very accurate (you needn't have rounded it to 8sf, it works up to 11sf ok), and quite fast (unlike Glenn's one, eh Glenn :wink: ), but toonski already did the taylor series so he is still winning. I'll continue this contest for another 3 days so you guys have a chance of catching toonski.
Here's Glenn's method:
Code:
'
' This function calculates the SINE of X by numerically solving the
' differential equation y''(x) + y = 0 via 2nd order Runge-Kutta, where
' y'' signifies the second derivitive of y(x) (and y(x) = sin(x)).
'
FUNCTION SINE#(X AS DOUBLE)
DIM Y AS DOUBLE,DYDX AS DOUBLE,DX AS DOUBLE,DYDX1 AS DOUBLE,N AS LONG
DIM I AS LONG,Y1 AS DOUBLE,Y0 AS DOUBLE,DYDX0 AS DOUBLE,DYDX2 AS DOUBLE
'
' Find a value for the differential stepsize as close as possible to
' .000005 in magnitude that divides X integrably.
'
DX=.000005#*SGN(X)
IF DX=0# THEN DX=.000005#
'
' N = number of iterations.
'
N=INT(X/DX)
IF N<1& THEN N=1&
DX=X/CDBL(N)
'
' Initialize iterations. (DYDX = first derivitive of y with respect
to
' x.)
'
Y=0#
DYDX=1#
'
' Don't try to calcucate SIN(0). That value is known.
'
IF ABS(X)>ABS(DX/10#) THEN
FOR I=1& TO N
Y0=Y
DYDX0=DYDX
'
' DYDX1 and DYDX2 are for Runge-Kutta update of DYDX. DYDX1 is for
step
' 1 and DYDX2 is for step 2.
'
DYDX1=-Y*DX
DYDX=DYDX+DYDX1
'
' Do step 1 of Y's iteration and step 2 of DYDX's.
'
Y=DYDX0*DX
DYDX2=-(Y+Y0)*DX
'
' Do step 2 of Y's iterations.
'
Y1=DYDX*DX
'
' Update Y and DYDX.
'
Y=Y0+(Y1+Y)/2#
DYDX=DYDX0+(DYDX1+DYDX2)/2#
NEXT I
END IF
SINE=Y
END FUNCTION
Careful of any line wrap... and it's the slowest possible way to calculate sine ever! Special award for Glenn!
05-30-2003, 03:47 AM
to do it by summing a bunch of Bessel functions.
05-30-2003, 04:55 AM
Quote:Heeh, I was just about to post with your method... :wink:
I have tested Mango's method. It's pretty good also, very accurate (you needn't have rounded it to 8sf, it works up to 11sf ok), and quite fast (unlike Glenn's one, eh Glenn :wink: ), but toonski already did the taylor series so he is still winning.
WOW!!! I got penalized for using the same method as toonski, yet his code/method weren't made public??!!! I say this whole bizness is rigged!! :lol:
Seriously, since you requested code not be posted, how can you give time preference to an earlier entry? My skin's pretty thick, though...no hard feelings.
Glen...I'm pretty new here and have been somewhat offput by some of your posts...until now...I understand the zen of your ways.
Cheers...
05-30-2003, 05:43 AM
It's okay, i'll split my cookie with you if i win. I dont really know why my peice of crap code I got from plugging in a formula without optimizing it is winning.