Creating a manual Sine Subroutine and Cosine Function in an external module?

ForteMP3

New member
Joined
May 8, 2005
Messages
1
Programming Experience
Beginner
Hello, I found this forum while doing a search for VB NET related forums, as I am in quite a predicament at the moment, and would appreciate some help from an expert on how to do what I'm trying to do.

First off, this is for a class project, one that will make or break my grade depending on its performance, so I NEED to make sure I get it done right or else I'll have to retake the entire course. I've had no trouble up until this point, because frankly, our instructor never covered the stuff we're expected to do on this final project, instead he focused on things like designing menus and making forms change color, which we never have used, not even for our final project.

Anyway, the requirements are simple, yet at the same time, kinda rediculous.

Our primary task is to create a module called trig.vb that will manually perform Sine and Cosine calculations in Radians.

The catch is the picky manner in which he wants this done...

A Factorial Function must be written (As far as I can tell, doing this with any variable type aside from Double causes an overflow error, due to the fact the factorials go into the range of 99!)

The Sine procedure must be done as a subprocedure in trig.vb, called from the main form.

The Cosine function must be done similarly to the Sine function, but as a Function instead of a Subroutine.

Currently, I'm having trouble getting the Sine function to work, based on what I was given.

The Sine formula we were given is essentially as follows, the following symbols will be explained before I write the formula to ensure clarity

^=Exponential value
!=Factorial of number.

Okay, having said that, here's what the Sine Subroutine should calculate...

sin(x)=x-x^3/3!+x^5/5!-x^7/7!...-x^99/99!

As far as I can tell, this ALONE would overload the program, considering you're doing every factorial and exponent from 1 to 99 in increments of 2.

The cosine function is similar, but with all addition, and it goes in an order of 2, 4, 6, 8, etc all the way to 100.

Anyway, here's the code I have so far. If anyone could help me with getting this to work, and finishing up the rest of the program, I would be eternally grateful.

This is in the main.vb form, and calls the sine function...

VB.NET:
Private Sub btnSine_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSine.Click
If IsNumeric(txtMain.Text) Then
Dim result As Double
result = txtMain.Text
Sine(result)
result = Math.Round(result, 2)
txtMain.Text = result
End If
End Sub
Next up, we have the trig.vb Factorial Function and Sine Subroutine...

VB.NET:
Function Factorial(ByVal N As Double) As Double
If N <= 1 Then
Return 1
Else
Return Factorial(N - 1) * N
End If
End Function
 
Public Sub Sine(ByRef value As Double)
Dim varSign As Double
Dim i As Double
Dim x As Double
x = value
varSign = -1
For i = 1 To 99 Step 2
value += (x ^ i / Factorial(i)) * varSign
varSign *= -1
Next i
End Sub
According to my assignment, the sine subroutine should return a value in the range of 0.5 when I enter .5322 as the value. I get something that rounds up to 0.02 instead. What's wrong with this?
 
Last edited by a moderator:
The issue, I think, is that in your Sine() function you've set x equal to value then started your loop from 1. You should either set x to 0, varSign to 1 and start your loop from 1 (which is the technically correct way to do it) or set x to value, varSign to -1 and start your loop from 3. I tried the following code and it worked perfectly:
VB.NET:
	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
		Me.NumericTextBox1.MinValue = Long.MinValue
		Me.NumericTextBox1.MaxValue = Long.MaxValue
		Me.NumericTextBox2.MinValue = Decimal.MinValue
		Me.NumericTextBox2.MaxValue = Decimal.MaxValue
		Me.NumericTextBox3.MinValue = Decimal.MinValue
		Me.NumericTextBox3.MaxValue = Decimal.MaxValue
	End Sub

	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
		Me.NumericTextBox2.Value = Math.Sin(Math.PI * Me.NumericTextBox1.Value / 180)
		Me.NumericTextBox3.Value = Me.Sin(Math.PI * Me.NumericTextBox1.Value / 180)
	End Sub

	Private Function Sin(ByVal x As Double) As Double
		Dim sign As Integer = 1
		Dim result As Double = 0

		For i As Integer = 1 To 99 Step 2
			result += sign * (x ^ i) / Me.Factorial(i)
			sign = -sign
		Next

		Return result
	End Function

	Private Function Factorial(ByVal n As Integer) As Double
		If n <= 1 Then
			Return 1
		Else
			Return n * Me.Factorial(n - 1)
		End If
	End Function
Note that a NumericTextBox inherits from TextBox, only accepts numeric input and has a Value property which is the numeric equivalent of the current Text. NumericTextBox1 only accepts Long values, which are interpreted as degrees (Math.PI * x / 180). NumericTextBox2 is read-only, displays floating point values and shows the actual sine value (Math.Sin()). NumericTextBox3 is read-only, displays floating point values and shows the my calculated sine value (Me.Sin()).
 
If your function has not yet worked because it is having an overflow, I am not surprised. It is not because the problem is demanding, but with all due respect, the implementation should NOT be using a factorial function, numerically speaking.
In fact, the algorithm you are required to use will accumulate more rounding errors than necessary because you are recalculating the powers and factorial at every term, up to 50 terms, when most of the time you only need 5 to 10 terms to calculate correctly to 5-7 figures.

Your teacher has good intentions to make you practise writing functions (factorial, etc), but with all due respect, it is not the best way to implement a sine or cosine function.

You will find the following implementation numerically very stable and efficient, because the factorial and the powers are calculated using previously obtained values, and a minimum of rounding error is retained.

VB.NET:
Private Function Sine(ByVal x as Double) as Double
Dim sum As Double = x
Dim term As Double = x
Dim x2 As Double = x*x
For i As integer = 3 to 99 Step 2
term=-term*x2/i/(i-1)
sum=sum+term
Next
Return sum
End Function
 
Similarly, the cosine is calculated as follows:
Private Function Cosine(ByVal x as Double) as Double
Dim sum As Double = 1
Dim term As Double = 1
Dim x2 As Double = x*x
For i As integer = 2 to 100 Step 2
term=-term*x2/i/(i-1)
sum=sum+term
Next
Return sum
End Function
Good luck with your project, and try to convince your teacher from REQUIRING the factorial function to be used.
 
Last edited by a moderator:
While what mathpath posted is all true and relevant, my guess is that the reason the project was designed the way it was is to demonstrate the use of recursion. The factorial function is a favourite for this purpose. I think you would almost always be able to find a more efficient way to solve a problem than using recursion, but it is still considered an important programming concept. Also note that the method I suggested produced correct results to about 10 decimal places or more.
 
I do understand that the whole project is an exercise in programming, perhaps recursion or other aspects. On the other hand, students are supposed to learn to do things the right way at school, because what they do there may be reused later on in real life.

A very practical application of the factorial function would be to calculate permutations and combinations, where integer arithmetic can be retained most of the time.

If I were to introduce the concept of summation of series to a class, even as a computer project, I would definitely cover the convergence aspect, as well as an idea when to terminate the summation, since retaining an arbitrary number of terms does not guarantee convergence to the true answer for large values of x in the case of sine and cosine.

Your point is very well taken, we have to leave the latitude to the teacher, but I still believe that an example should remain an appropriate application of the pertinent principles.
 
I have the same project and I am in need of some help. I understand vb but didn't pay much attention when modules and functions were being discussed.:rolleyes:

If someone could help me with this, it would be much appreciated.

thanks
 
Back
Top