Reputation: 149
I'm trying to evaluate the approximation of sin of 1.89 using a Taylor approximation. I compared the output to the value from Math.sin(x); however, after about 14 terms my value deviates quite largely and becomes erroneous. I tried the approximation for a smaller value of x ( <0.5), and the values match.
I'm just trying to figure out why Java, using sublime and being complied via bash on Mac OSx deviates from the true output.
public class Test {
public static void main (String[] args) {
double x = 1.89;
double sinx = 0;
int n = 20;
int countOdd = 1;
int counter = 1;
int result = 0;
int value = 0;
while (countOdd <= n) {
if (counter%2 != 0) {
// Even term odd number
if (countOdd%2 == 0) {
sinx = sinx - (Math.pow(x,counter)/(double)factorial(counter));
System.out.println(" counter even odd term = " + countOdd);
countOdd++;
System.out.println(" sinx = " + sinx);
}
// Odd term odd number
else {
sinx = sinx + (Math.pow(x,counter)/(double)factorial(counter));
System.out.println(" counter odd odd term = " + countOdd);
countOdd++;
System.out.println(" sinx = " + sinx);
}
}
// Update the result and reset the value
//sinx = sinx + value;
//value = 0;
System.out.println(" counter = " + counter);
counter++;
}
System.out.println(" sinx = " + sinx);
System.out.println(" sinx from math library = " + Math.sin(x));
}
/** calcutes and returns n!
@param n : a positive integer number
@return n!
*/
public static int factorial(int n)
{
// your code goes here
int result = 1; // if n = 0, while loop is by passed and 0 is returned
while (n >= 1) {
result = result * (n);
n--;
}
return result;
}
}
Upvotes: 1
Views: 448
Reputation: 48307
the reason is here:
public static int factorial(int n) {
int result = 1;
while (n >= 1) {
result = result * (n);
n--;
}
return result;
}
you are not considering the fact that factorial converges very fast generating an overflow (some results are negative numbers then)
you can verify that beh. splitting a little the code where factorial returned value is used:
while (countOdd <= n) {
if (counter % 2 != 0) {
// Even term odd number
if (countOdd % 2 == 0) {
int factorial = factorial(counter);
System.out.println("factorial: " + factorial);
sinx = sinx - (Math.pow(x, counter) / factorial);
System.out.println(" counter even odd term = " + countOdd);
countOdd++;
System.out.println(" sinx = " + sinx);
}
// Odd term odd number
else {
int factorial = factorial(counter);
System.out.println("factorial: " + factorial);
sinx = sinx + (Math.pow(x, counter) / factorial);
System.out.println(" counter odd odd term = " + countOdd);
countOdd++;
System.out.println(" sinx = " + sinx);
}
}
as you will note, the output will produce negative values which are distroying the numeric approximation you want to achieve
...
counter even odd term = 10
sinx = 0.9476740866450655
counter = 19
counter = 20
factorial: -1195114496
Upvotes: 1
Reputation: 1306
It is recommended to use BigDecimal
instead of double
and int
for large numerical calculations like factorial and power.
Upvotes: 2