I have to write a program that returns the square root of any number that is inputted. My method runs fine for any number that has a perfect square (like 25 or 100) but if I use any number that doesn't (3 or 10) I get a stack overflow error. I was hoping some one could tell me what I did wrong and how I could fix it.
public boolean sqrRootRecursive(int number, double approx, double tol)
{
if( (Math.abs((Math.pow(approx,2) - number))<= tol))
{
System.out.println("The root is " +approx);
}else if (Math.abs((Math.pow(approx,2)-number))>tol)
{
sqrRootRecursive(number, ((Math.pow(approx,2)+number)/(2*approx)), tol);
}
return true;
Thanks for the help!
It is the same problem as Newton Raphson iteration trapped in infinite loop and i am giving pretty much the same answer.
It should be (Math.abs((Math.pow(approx,2) - number))<= tol*number)
It the number is very large, Math.abs((Math.pow(approx,2) - number)) will hardly become lower than tol due to the precision of floating point computation. It may work for some numbers and fail for others, which corresponds to the symptoms described in the question. The right test is <tol*number.
If number is very small, Math.abs((Math.pow(approx,2) - number)) will become lower than tol before getting close to sqrt(number). Once again, using <tol*number will solve this problem.
By using (Math.abs((Math.pow(approx,2) - number))<= tol*number), the right side and the left side of the test have compatible units, since a tolerance is dimensionless.
If it does not solve the stack overflow, increase tol or add a counter and a max number of recursive call.
Related
I found a simple Java exercise and I answered it, yet there seems to be an issue with my code and I can't seem find the problem. Please point me towards the issue:
The problem is:
We want to make a row of bricks that is goal inches long. We have a number of small bricks (1 inch each) and big bricks (5 inches each). Return true if it is possible to make the goal by choosing from the given bricks. This is a little harder than it looks and can be done without any loops.
And I made this function as answer:
public boolean makeBricks(int small, int big, int goal) {
if (small>=goal) return true;
if ((goal>=5) && (big>=1)){ makeBricks(small,big-1,goal-5);}
return false;
}
Yet when running it on https://codingbat.com/prob/p183562 it says that it's wrong and it all looks correct to me.
Adding a return statement fixes your technical problem of being unable to determine the truth value of calls further down the stack, but that's a linear solution to a problem that can be solved in constant time with basic math:
public boolean makeBricks(int small, int big, int goal) {
return big * 5 + small >= goal && goal % 5 <= small;
}
The idea here is to first determine if all of our bricks combined meets or exceeds the goal: big * 5 + small >= goal. If we can't satisfy this equation, we're definitely out of luck.
However, this is overly optimistic and does not account for cases when we have sufficient blocks to exceed the goal but not enough small blocks to remove some number of larger blocks and meet the goal. Testing goal % 5 <= small ensures that we have enough small blocks to bridge the gap of 5 that will be left as each large block is removed.
If that's still not clear, let's examine an edge case: makeBricks(3, 2, 9). Our goal is 9 and we have 3 small blocks and 2 large ones. Combining our entire arsenal gives a total of 13, which seems sufficient to meet the goal. However, if we omit one of our large blocks, the closest we can get is 8. If we omit all of our small blocks, the closest we can get is 10. No matter what we do, the goal is one block out of reach.
Let's check that against our formula: 9 mod 5 == 4, which is 1 more than our number of small blocks, 3, and matches our hand computation. We should return false on this input. On the other hand, if we had 1 extra small block, 9 % 5 == small would be true, and we'd have just enough blocks to bridge the gap.
Put a return in front of your recursive call:
return makeBricks(small,big-1,goal-5);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
The sum to infinity of the following series is to be found:
1 1/2 1/3 1/4 1/5 ...
According to the explanation of a certain scientist, infinity is that point beyond which any point is non existent, i.e., inf + x = inf or inf ~ (inf + x) = 0. So, based on this theory, the following algorithm was used:
float sum=0.0;
for(int i=0;;i++){
if((sum+(1.0/i))==sum)
break;
sum+=(1.0/i);
}
/* print the value of sum */
The algorithm was run in C and JAVA and both gave the output as inf. The print statements written in C and Java respectively are
printf("%6f",sum);
System.out.println(sum);
EDIT:
The code written earlier (in the question) had a mistake because I typed it, didn't copy-paste. Sorry for that. That being solved, here's the code I'd base my question upon:
float sum=0.0;
for(int i=1;;i++){
if((sum+ (1.0/i))==sum)
break;
sum+=(1.0/i);
}
/*print the value of sum*/
A friend of mine said he got the output as a finite fractional number in C. But in my case, the program never terminated, both in C and Java(This output was got from the new edited code posted above. Do not consider the previous faulty code and it's output which was "INF".) My question is, is this algorithm acceptable? And if yes, then I'd like to know the possible of cause different outputs in C. Thanks.
The algorithm was run in C and JAVA and both gave the output as inf.
That is because there is a bug in your code. You are starting with i == 0. When you calculate 1.0 / 0 you get an INF.
The series is supposed to start with i == 1 ...
You edited the question to fix to that particular bug.
Even so, you still will never get a correct value for the sum to infinity. The series diverges (goes to infinity) but given the way you are calculating it, there is no way that you will get there.
Eventually, you will reach a point where 1.0/i is too small to change sum and you will break out of the loop. I expect that will happen before i == Integer.MAX_VALUE ... but if it didn't, then you would run into ANOTHER bug in your code. If i ever reached Integer.MAX_VALUE then it would wrap around to Integer.MIN_VALUE and you will start adding negative terms to the sum. Oops!
Actually, what you are trying to calculate is the Harmonic Series. The partial sums (for N terms) converge to loge N + E, where E is the Euler–Mascheroni constant.
Source: https://en.wikipedia.org/wiki/Harmonic_series_%28mathematics%29#Partial_sums
From this, one should be able to estimate when the difference between Nth partial sum and 1.0 / N becomes large enough to stop the iteration.
A final note: you will get more accurate sums if you sum in the opposite direction; i.e. starting with very large N and summing with N reducing to 1.
There are many problems with your code. Your program doesn't work, it only seems to work.
Never compare float numbers for equality.
Computers can't divide by zero.
Literals 0.0 are of type double. Meaning that the calculation sum+(1.0/i) is performed on type double, which might be a larger type than float on the particular system. Your code assumes that float and double have the same representation, so it is non-portable.
Therefore the result may not be too large during the calculation, which is done on type double, but it doesn't fit when you try to show it back into a float. Instead use f prefix on all literals, that is: 1.0f. Or just use double consistently all over the program.
Avoid cryptic loops. There's no need to move the loop condition inside the loop body. Your loop should look something like for(int i=0; float_compare(sum+1.0f/i, sum); i++), where float_compare is some way to compare float numbers. Something like this:
#include <math.h>
#define EPSILON 0.00001f
inline bool float_compare (float x, float y)
{
return fabsf(result - expectedResult) < EPSILON;
}
Some notes The range of i is important - integers have only fixed representations.
The series 1/1 + 1/2 + 1/3 + 1/4 ... is divergent (wikipedia : sum of recipricals)
The range of an int wraps, and so you would also be adding -1/1 -1/2 ... which would tend to 0.
The series progresses to infinity very slowly, so a computer may not be the best way of working it out.
So I am making an application that can solve problems with Empirical Formulae and I need some code that would do something like:
If numbers are 2.5, 1, 3 it should change them to 2.5*2 = 5, 1*2 = 2, 3*2 = 6 so that the number with the decimal is converted to a whole number and the other numbers are adjusted appropriately.
I thought of this logic:
for(n = 1; (Math.round(simplestRat[0]) * n) != (int)SimplestRat[0]; n++)
to increment a counter that would multiply an integer to do what I want it to but I am skeptical about this code even at this phase and do not think it will work.
It would be a lot of help if someone could suggest a code for this or improve upon this code or even give me a link to another post for this problem as I was unable to find anything regarding this type of problem.
Any help is appreciated. Thanks
Okay, so you have to have a few steps. First, get them all into whole numbers. The easiest way is to find an appropriate power of ten to multiply them all by that leaves them as integers. This is a useful check: How to test if a double is an integer.
Then cast them to integers, and start working through them looking for common prime factors. This'll be a process similar to Eratosthenes' Sieve (http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) but with division at the end. For each prime, see if all 3 numbers divide by it exactly (modulo prime == 0). If they do, divide and reset the primes to 2. If they don't, next prime.
This should give you the lowest common ratio between the numbers. Any additional multiplier that came from the original stage is shaved off by the common primes method.
As you can see from the title, I'm busy programming a little programm for visualizing fractals in Java. Anybody who deals with fractals will come to the point where he/she searches for a solution to get these stupid "bands" away, when you just colour a pixel by the number of iterations it took to escape.
So I searched for a more advanced colouring algorithm, finding the "normalized iteration count". The formula I'm using is:
float loc = (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);
Everybody on the Internet is so happy about this algorithm, everybody uses it, everbody gets great results. Except me. I thought, this algorithm should provide a float between 0 and 1. But that doesn't happen. I did some calculations and came to the conclusion, that this algorithm only works for c.abs() >= Math.E && c.abs() <= Math.exp(2) (that is Math.E * Math.E).
In numbers this means, my input into this equation has to be between about 2.718 and 7.389.
But a complex number c is considerd to tend towards infinity when its magnitude gets greater than 2. But for any Input smaller than Math.E, I get a value greater than one. And for any number greater than Math.exp(2), it gets negative. That is the case if a complex number escapes really fast.
So please tell me: what am I doing wrong. I'm desperate.
Thanks.
EDIT:
I was wrong: the code I posted is correct, I just
1. used it the wrong way and so it didn't provide the right output.
2. had to set the bailout value of the mandelbrot/julia algorithm to 10, otherwise I would've got stupid bands again.
Problem solved!
As you've already discovered, you need to increase the bailout radius before smoothing will look right.
Two is the minimum length that a coordinate can have such that when you square it and add the initial value, it cannot result in a smaller length. If the previous length was 2.0, and you squared it, you'd have a length of 4.0 (pointing in whichever direction), and the most that any value of c could reduce that by is 2.0 (by pointing in precisely the opposite direction). If c were larger than that then it would start to escape right away.
Now, to estimate the fractional part of the number of iterations we look at the final |z|. If z had simply been squared and c not added to it, then it would have a length between 2.0 and 4.0 (the new value must be larger than 2.0 to bail out, and the old value must have been less than 2.0 to have not bailed out earlier).
Without c, taking |z|'s proportional position between 2 and 4 gives us a fractional part of the number of iterations. If |z| is close to 4 then the previous length must have been close to 2, so it was already close to bailing out in the previous iteration and the smoothed result should be close to the previous iteration count to represent that. If it's close to 2, then the previous iteration was further from bailing out, and so the smoothed result should be closer to the new iteration count.
Unfortunately c messes that up. The larger c is, the larger the potential error is in that simple relationship. Even if the old length was nearly at 2.0, it might have landed such that c's influence made it look like it must have been smaller.
Increasing the bailout mitigates the effect of adding c. If the bailout is 64 then the resulting length will be between 64 and 4096, and c's maximum offset of 2 has a proportionally smaller very impact on the result.
You have left out the iteration value, try this:
float loc = <iteration_value> + (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);
The iteration_value is the number of iterations which yielded c in the formula.
Why can't java gracefully return some value with a division by zero and instead has to throw an Exception?
I am getting an ArrayIndexOutOfBoundsException:0 This is because because damageTaken is actually an array of values that stores many different 'damages'.
In java I'm trying to create a progress bar. Our example: damage incurred, in a racing game, by setting the value for height as a percentage of maxmimum damage allowed before gameover.
At the start of the program damageTaken = 0;
(damageTaken / maximumDamage)
will give numbers between 0 - 1.
Then I just multiply that by the height of the progress bar, to create a fill bar of the appropriate height.
The program crashes. I want the progress bar to be of zero height!
You are not dividing by zero, you are dividing zero by something.
It is completely allowed to take two halves of zero. The answer is zero. Say you have zero apples. You split your zero apples between Alice and Bob. Alice and Bob now both have zero apples.
But, you cannot divide by zero. Say you have two apples. Now, you want to give these apples to zero people. How many apples does each person get? The answer is undefined, and so division by zero is impossible.
(damageTaken / maximumDamage)
This gives you a division by zero exception only if maximumDamage is zero.
If damageTaken is zero, there is no problem.
Just add a special case for 0;
private int getProgress()
if (damageTaken == 0) {
return 0;
} else {
return (damageTaken / maximumDamage) * progress.getHeight();
}
}
However, (and it's a big however) the reason you are getting divide by 0 is because maximumDamage is 0, not damageTaken. So, what you probably really want is:
private int getProgress()
if (maximumDamage== 0) {
return 0;
} else {
return (damageTaken / maximumDamage) * progress.getHeight();
}
}
Conceptually, having 4/0 yield some arbitrary number would be no worse than having an attempt to double a count of 2000000000 yield a count of -294967296. Most processors, however, will ignore most kinds of arithmetic overflow unless one explicitly checks for it, but cannot ignore an attempt to divide by zero unless one explicitly checks the operands beforehand (and skips the operation if they are invalid). Given that many processors have "overflow" flags, nothing would prevent a processor from specifying that an attempted divide-by-zero should simply do nothing but set the overflow flag (a successful divide operation should clear it); code which wants to trigger an exception in such a case could do so.
I suspect the reason for the distinct behavior stems from the early days of computing; the hardware for a division instruction could judge that it was complete when the remainder was less than the divisor. If that never happened, the instruction could get stalled until a general supervisory clock circuit (designed to signal a fault if for whatever reason instructions stop being executed) shut things down. Hardware to detect the problem and exit without stalling the CPU would have been trivial by today's standards, but in the days when computers were built from discrete transistors it was cheaper, and almost as effective, to tell programmers do not attempt to divide by zero, ever.
Let's stop talking about illegality, as though uniformed mathematics police were about to storm the room. ;) For the mathematical reasoning behind this, this related question is useful.
It is fair to ask why, after all this time, modern programming platforms don't handle division-by-zero errors for us in some standard way - but to answer the question: Java, like most any other platform, throws an error when division by zero occurs. In general, you can either:
Handle before: check the variable to be used as your denominator for zero before doing the division
Handle after: you can catch the exception thrown when the division by zero occurs and handle it gracefully.
Note that, as good practice, the second method is only appropriate when you wouldn't expect the variable to ever be zero under normal system operation.
So yes, you need a special case to handle this situation. Welcome to programming. ;)