Stack Overflow Error (Java) - java

So my code is printing out estimations of Pi using a for and while loop and a recursive method. It's all working except my compiler is saying there's a stack overflow error for the if statement in my recursive method.
public static final double REAL_PI = 3.14159;//PI is the value Mr.B gave us on the handout
public static double Pi = 0; //Pi is the value of Pi that this program calculates
public static int m = 0;
public static int c = 0;
public static void main (String [] args)
{
Algorithm(); //calls on method of calculating pi
System.out.println("Calculated pi: " + Pi); //prints out pi
countDigits(Pi); //calls on countdigits method
System.out.println("Number of digits: " + c); //has the computer print out the count because that's how many digits are the same
While();
Recursive(1, 0.0); //calls on estimate digits method
}
public static double Algorithm() //should return a double (pi)
{
for(m=1; m<=100000; m++)
{
Pi += 4*(Math.pow(-1, m-1)/((2*m)-1));//Math.pow uses math package to calculate a power to use the algorithm
}
return Pi;
}
public static int countDigits (double Pi)
{
int a = (int) Pi; //the int cast makes Pi and REAL_PI into integers so the program can compare each digit separately
int b = (int) REAL_PI;
int c = 0;
int count = 0;
while(a == b)//if m less then or equal to 100,000 then while loop runs
{
count ++;
a = (int) (Pi*(Math.pow(10,count))); //if a=b then the computer will multiply Pi and REAL_PI by 10
b = (int) (REAL_PI*(Math.pow(10,count)));
/*when you input a and b
* while loop compares them
* if a = b then loop continues until a doesn't equal b and loop ends
*/
}
c = count; //gives c the value of the count so it can be used outside the method
return count;
}
public static double While()
{
int m = 1;
Pi = 0.0;
while (countDigits(Pi) < 6)
{
Pi += 4*(Math.pow(-1, m-1)/((2*m)-1));
m++;
}
Pi = (int)(Pi * 1000000);
Pi = (double)(Pi/1000000);
System.out.println("Pi using while loop: " + Pi);
return Pi;
}
public static double Recursive(int m,double Pi)
{
Pi += 4*(Math.pow(-1, m-1)/((2*m)-1));
if (countDigits(Pi) < 6)
{
return Pi += Recursive(m+1,Pi);
}
Pi = (int)(Pi * 1000000);
Pi = (double)(Pi/1000000);
System.out.println("Pi using recursive: " + Pi);
return Pi;
}
}

The problem is that the Leibniz series for computing π converges EXTREMELY slowly. Using your program, I found that after 3663 iterations (when I killed the program), the values looked like this:
pi=3.141865802997432
pi=3.1413195787723875
pi=3.1418656538577117
pi=3.1413197278306884
Still only 3 decimal places, and it is going to take a long time even to be accurate to 4. The stack is not big enough to hold so many recursive calls, and eventually it will overflow.

Related

How to add multiple numbers using nested loops?

I am doing an assignment where I must use nested loops in order to add up the squares and cubes of integers from 1 to N (N being whatever the user inputs). For example, if the user input the number 5, the program is supposed to do "1²+2²+3²+4²+5²" and output the sum of those numbers, as well "1³+2³+3³+4³+5³" and output the sum of those numbers.
However, I am having trouble figuring out how to code it in a way that I receive the proper output? This is what I wrote. Scanners were already added.
int limitNum = input.nextInt();
double squareNums:
double sumofSq = 0;
double cubedNums;
double sumofCubes = 0;
for(int s = 1; s <= limitNum; s++)
{
for(int c = 1; c <= limitNum; c++)
{
cubedNums = Math.pow(c, 3);
sumofCubes = sumofCubes + cubedNums;
}
squareNums= Math.pow(s, 2);
sumofSq = sumofSq + squareNums;
}
But currently, when I run this program, the sum of the squares output correctly, but the sum of the cubes is always some big number. For example if 5 is used, sumofSq would output 55.0, but sumofCubes would output 1125.0.
There is no point using a nested loop as this would result in complexity of O(n²). A single loop would be sufficient and be in complexity class O(n).
public class Application {
public static void main(String[] args) {
var squareSum = 0d;
var cubeSum = 0d;
var upperBound = 5;
for(var i = 1; i <= upperBound; i++){
squareSum += Math.pow(i, 2);
cubeSum += Math.pow(i, 3);
}
System.out.printf("""
Sum of first n squares: %s
Sum of first n cubes: %s
""", (int)squareSum, (int)cubeSum);
}
}
In fact there is no need to loop at all => constant computation time no matter the size of the input O(1). There is a well known formula which tells you the sum of the first n squares.
n(n+1)(2n+1)
------------
6
Please see this for a proof.
The same holds true for the first n cubes.
n²(n+1)²
--------
4
Please see this for a proof.
The following program will therefore return the same result.
public class Application {
public static void main(String[] args) {
var upperBound = 5;
System.out.printf("""
Sum of first n squares: %s
Sum of first n cubes: %s
""", sumOfFirstNSquares(upperBound), sumOfFirstNCubes(upperBound));
}
public static int sumOfFirstNSquares(int n){
return (n * (n+1) * (2 * n + 1)) / 6;
}
public static int sumOfFirstNCubes(int n){
return ((n * n) * (n+1) * (n+1)) / 4;
}
}
In fact there is no need to loop at all => constant computation time no matter the size of the input O(1). There is a well known formula which tells you the sum of the first n squares.
java

How do I change Procedural Programming into OOP..? (JAVA)

I am a beginner Java programmer and have toiled over this for quite some time. I need to convert the program below into OOP format and cannot get it to compile without error. I figured I would post the working non-formatted program rather than my failed and choppy attempts. If anyone could convert the below program into OOP, it would be very much appreciated. Please forgive any inefficiencies or sloppiness as I am new to this.
Thanks for helping :)
import java.util.Scanner;
public class EstimatePi
{
//Public static variables used because they are used throughout the different methods
public static Scanner in = new Scanner(System.in);
//2 * Math.random - 1 is used to guarentee that the max value is gonna be 1 and min is gonna be -1
public static double x = (2 * Math.random() - 1);
public static double y = (2 * Math.random() - 1);
public static double radius = 1.0;
public static double numOnBoard;
public static double totalPi;
public static int numThrows;
public static int trials;
public static int hits(double x, double y, int trials) {
numOnBoard = 0;
for (int i = 1; i < trials; i++) {
//Same Algorithm as above
x = (2 * Math.random() - 1);
y = (2 * Math.random() - 1);
//If x2 + y2 <= r2 then its a hit on the board.
if ((Math.pow(x, 2) + Math.pow(y, 2)) <= (Math.pow(radius, 2))) {
numOnBoard++;
}
}
//returns the num of hits on the board
return (int)numOnBoard;
}
//Method to calculate pi, and store that data in an array
public static double[] piColumn( double numOnBoard, double numThrows)
{ double []piColumn = new double[trials];
for(int i = 0; i < piColumn.length;i++)
{
//Formula to calculate the pi
piColumn[i] = (4 * (numOnBoard) / numThrows);
}
return piColumn;
}
public static void main (String [ ] args)
{
//The number of darts thrown per trial is asked
System.out.println("How many times should the dart be thrown per trial?");
numThrows = in.nextInt();
System.out.println();
//The number of trials is asked
System.out.println("How many trials do you want to simulate?");
trials = in.nextInt();
System.out.println();
//forloop to iterate the internal code while counter < trials
for (int counter = 0; counter < trials; counter++) {
//number of hits methods is declared as a integer
int hits = hits(x,y,numThrows);
//the calculation of pi is declared as a double
double []estimatedPi = piColumn(hits,numThrows);
//total = total + the estimatation of pi
for(int i = 0; i < trials; i++){
totalPi += estimatedPi[i];
}
//Formatting the output
System.out.printf("%s %d %s %s", "Trial [",(counter + 1),"]", ": pi = ");
System.out.printf("%1.5f\n",estimatedPi[counter]);
}
//The average pi is the total pi's divided by the number of trials the user enters
double averagePi = (totalPi / trials / trials);
System.out.printf("%s %1.5f\n", "Estimation of pi = ",averagePi);
}
}
I was inspired by the question and wrote a comic project. I tried to make the code as more as possible object oriented, but stay in "domain" and do not use heavily design patterns, frameworks, etc. Also, I tried to follow test-first ideology. You can view commits history and see how the work went step by step.
Thank you, javacoder, for the experience and fun.

Create a program that calculates the square root of a number without using Math.sqrt

This is the formula that can be used to calculate the square root of a number.
result=(guess+(number/guess))/2;
For example, I need to get the square root of 9. First, I need to make a guess. For this one, it's 6. Although, I know that the square root of 9 is 3, I chose 6 to show how the program should work.
that makes...
result=(6+(9/6))/2 which is equal to 3.75.
To get the actual square root of 9, I need to make the result the new guess.The program should continue as...
result=(3.75+(9/3.75))/2 which is equal to 3.075.
This process should continue till difference between result and the result after it is equal to 0. For example
result=(3+(9/3))/2 is always equal to 3.
When the value of result is passed to guess, the next result will also be 3. That means 3 is the square root of nine.
Here's my code:
package javaPackage;
public class SquareRoot {
public static void main(String[] args) {
calcRoot();
}
public static void calcRoot(){
double num=9;
double guess=6;
double result=0;
while(Math.abs(guess-ans)!=0){
result=(guess+(num/guess))/2;
guess=result;
}
System.out.print(result);
}
}
Output
3.75
My problem is I can't compare the value of result and the previous result. Since guess is equal to result, the program immediately since guess and result are already equal. How can I fix it?
Just exchange the two statements in the while loop (and the initializations to avoid a division by zero):
public static void calcRoot(){
double num=9;
double guess=0;
double result=6;
while(Math.abs(guess-result)!=0){
guess=result;
result=(guess+(num/guess))/2;
}
System.out.print(result);
}
The trick is to have the old value still in guess and the new one in result when the test is executed.
And you should not test for != 0, due to rounding errors this may not be achieved. Better test for some small value >= 1e-7
To compare the result with the previous result you need to keep both of them in a variable.
This does a binary chop.
public static double sqrt(double ans) {
if (ans < 1)
return 1.0 / sqrt(1.0 / ans);
double guess = 1;
double add = ans / 2;
while (add >= Math.ulp(guess)) {
double guess2 = guess + add;
double result = guess2 * guess2;
if (result < ans)
guess = guess2;
else if (result == ans)
return guess2;
add /= 2;
}
return guess;
}
public static void main(String[] args) {
for (int i = 0; i <= 10; i++)
System.out.println(sqrt(i) + " vs " + Math.sqrt(i));
}
prints
0.0 vs 0.0
1.0 vs 1.0
1.414213562373095 vs 1.4142135623730951
1.7320508075688772 vs 1.7320508075688772
2.0 vs 2.0
2.236067977499789 vs 2.23606797749979
2.449489742783178 vs 2.449489742783178
2.64575131106459 vs 2.6457513110645907
2.82842712474619 vs 2.8284271247461903
3.0 vs 3.0
3.162277660168379 vs 3.1622776601683795
and
for (int i = 0; i <= 10; i++)
System.out.println(i / 10.0 + ": " + sqrt(i / 10.0) + " vs " + Math.sqrt(i / 10.0));
prints
0.0: 0.0 vs 0.0
0.1: 0.31622776601683794 vs 0.31622776601683794
0.2: 0.4472135954999581 vs 0.4472135954999579
0.3: 0.5477225575051662 vs 0.5477225575051661
0.4: 0.6324555320336759 vs 0.6324555320336759
0.5: 0.7071067811865476 vs 0.7071067811865476
0.6: 0.7745966692414834 vs 0.7745966692414834
0.7: 0.8366600265340758 vs 0.8366600265340756
0.8: 0.894427190999916 vs 0.8944271909999159
0.9: 0.9486832980505138 vs 0.9486832980505138
1.0: 1.0 vs 1.0
Just create another variable to store the value of the previous guess.
This is the code:
package javaPackage;
public class SquareRoot {
public static void main(String[] args) {
calcRoot();
}
public static void calcRoot(){
double num=9;
double guess=6;
double prevGuess=0;
double result=0;
while(Math.abs(guess-prevGuess)!=0){
result=(guess+(num/guess))/2;
prevGuess = guess;
guess=result;
}
System.out.print(result);
}
}
For performance,following this code:
public static double sqrt(double num) {
double half = 0.5 * num;
long bit = Double.doubleToLongBits(num);
bit = 0x5fe6ec85e7de30daL - (bit >> 1);
num = Double.longBitsToDouble(bit);
for (int index = 0; index < 4; index++) {
num = num * (1.5f - half * num * num);
}
return 1 / num;
}
About the magic number 0x5fe6ec85e7de30daL,you can see the FAST INVERSE SQUARE ROOT
Let's see the performance,the test code:
double test = 123456;
//trigger the jit compiler
for (int index = 0; index < 100000000; index++) {
sqrt(test);
}
for (int index = 0; index < 100000000; index++) {
Math.sqrt(test);
}
//performance
long start = System.currentTimeMillis();
for (long index = 0; index < 10000000000L; index++) {
sqrt(test);
}
System.out.println("this:"+(System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (long index = 0; index < 10000000000L; index++) {
Math.sqrt(test);
}
System.out.println("system:"+(System.currentTimeMillis() - start));
System.out.println(sqrt(test));
System.out.println(Math.sqrt(test));
and the result is:
this:3327
system:3236
this result:351.363060095964
system result:351.363060095964
public static double sqrt(double number)
{
double dd=number, sqi, sqrt=0;
long i, b=0, e=0, c=1, z, d=(long)number, r=0, j;
for (i=1l, sqi=1; ; i*=100l, sqi*=10)
{
if (i>dd)
{
i/=100;
sqi/=10;
j=i;
break;
}
}
for (z=0l; z<16; dd=(dd-(double)(r*i))*100, j/=100l, sqi/=10, z++)
{
r=(long)(dd/i);
d=(e*100l)+r;
int a=9;
for (c=((b*10l)+a)*a; ; a--)
{
c=((b*10l)+a)*a;
if (c<=d)
break;
}
//if (a>=0)
// System.out.print(a);
e=d-c;
sqrt+=a*sqi;
if (number==sqrt*sqrt && j==1)
break;
//if (j==1)
// System.out.print('.');
b=b*10l+2l*(a);
}
return sqrt;
}
Sorry for the undefined variable names....but this program really works!
This program is based on long division method of finding square root

Using loops to compute factorial numbers, Java

I'm trying to compute the value of 7 factorial and display the answer, but when I tried to look up a way to do this I kept finding code that was written so that a number first had to be put in from the user and then it would factor whatever number the user put in. But I already know what number I need, obviously, so the code is going to be different and I'm having trouble figuring out how to do this.
I tried this at first
public class Ch4_Lab_7
{
public static void main(String[] args)
{
int factorial = 7;
while (factorial <= 7)
{
if (factorial > 0)
System.out.println(factorial*facto…
factorial--;
}
}
}
But all it does is display 7*7, then 6*6, then 5*5, and so on, and this isn't what I'm trying to do.
Does anyone know how to do it correctly?
import java.util.Scanner;
public class factorial {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
//Gives Prompt
System.out.print("Enter a number to find the factorial of it");
//Enter the times you want to run
int number = input.nextInt();
//Declares new int
int factor = 1;
//Runs loop and multiplies factor each time runned
for (int i=1; i<=number; i++) {
factor = factor*i;
}
//Prints out final number
System.out.println(factor);
}
}
Just keep multiplying it and until it reaches the number you inputted. Then print.
Input:5
Output:120
input:7
Output:5040
You need to have two variables, one for the factorial calculation and other for the purpose of counter. Try this, i have not tested it but should work:
public static void main(String[] args)
{
int input = 7;
int factorial = 1;
while (input > 0)
{
factorial = factorial * input
input--;
}
System.out.println("Factorial = " + factorial);
}
int a=7, fact=1, b=1;
do
{
fact=fact*b;//fact has the value 1 as constant and fact into b will be save in fact to multiply again.
System.out.print(fact);
b++;
}
while(a>=b); // a is greater and equals tob.
1st reason:
The methods you seen are probably recursive, which you seem to have edited.
2nd:
You are not storing, ANYWHERE the temporal results of factorial.
Try this
//number->n for n!
int number = 7;
//We'll store here the result of n!
int result = 1;
//we start from 7 and count backwards until 1
while (number > 0) {
//Multiply result and current number, and update result
result = number*result;
//Update the number, counting backwards here
number--;
}
//Print result in Screen
System.out.println(result);
Try this:
public static void main(String args[]) {
int i = 7;
int j = factorial(i); //Call the method
System.out.println(j); //Print result
}
public static int factorial(int i) { //Recursive method
if(i == 1)
return 1;
else
return i * factorial(i - 1);
}
This would print out the factorial of 7.
public class Factorial {
public static void main(String[] args) {
int result = factorial(5); //this is where we do 5!, to test.
System.out.println(result);
}
public static int factorial(int n) {
int x = 1;
int y = 1;
for (int i = 1; i <= n; i++) {
y = x * i;
x = y;
}
return y;
}
}
/*so, for 3! for example, we have:
i=1:
y = x * i, where x = 1, so that means:
y = 1*1 ; y= 1; x = y so x = 1. Then i increments =>
i = 2:
y = x * i. x is 1 and i is 2, so we have y = 2. Next step in code: x=y, means x = 2. Then i increments =>
i = 3:
y = x *i so we have y = 2*3. y=6. */

Java - raise Real To Power n^k

I'm having difficulty writing a program to solve this exercise from a Java text book:
Write a method raiseRealToPower that takes a floating-point value x and an integer
k and returns xk. Implement your method so that it can correctly calculate the result
when k is negative, using the relationship
x^(-k) = 1 / x^k.
Use your method to display a table of values of πk for all values of k from –4 to 4.
I didn't done this part with PI, i know that, if my programs starts to work... this is what i done... tell me please, what is wrong.
import acm.program.*;
public class vjezba55 extends ConsoleProgram {
private static final double PI = 3.14159253;
public void run() {
double x = readDouble ("x: ");
double k = readDouble ("k: ");
println ("x^k = " + raiseDoublePower(x,k));
}
/* Method that counts x^k */
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
double total = 1;
for (int i= 0; i>k; i--) {
total = (double) 1 / x;
}
return total;
}
}
}
Take a look at your loop code. You are just recalculating total from scratch on each iteration, rather than updating the previous result.
I don't understand the part in the question regarding PI, but your method may be much simpler (according to using the relationship x^(-k) = 1 / x^k):
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
return 1 / Math.pow(x, -k);
}
}

Categories

Resources