Compute Logarithm
I'm trying to write a method that takes in a base k and a value n to 2 decimal places, then computes the log base k of n without using any of Java's Math.log methods. Here's what I have so far:
public static double log(double k, double n) {
double value = 0.0;
for(double i = 1;开发者_Go百科 i > .001; i /= 10) {
while(!(Math.pow(k, value) >= n )) {
value += i;
}
}
return value;
}
The problem comes up when I try computing log base 4 of 5.0625, which returns 2.0, but should return 1.5.
I have no idea why this isn't working. Any help is appreciated.
No this is not homework, it's part of a problem set that I'm trying to solve for fun.
You're adding the amount i
once too ofter. Thus you'll quite soon reach a value larger than the actual value and the while loop will never be entered again.
Subtract i
once from the value and you'll be fine:
for(double i = 1; i > .001; i /= 10) {
while(!(Math.pow(k, value) > n )) {
value += i;
}
value -= i;
}
Step through the code on paper:
Iteration: i=1 value = 0.0, calculated power = 1
Iteration: i=1 value = 1.0, calculated power = 4
Iteration: i=1 value = 2.0, calculated power = 16
Now at this point, your value is 2.0. But at no point in the code to you have a way to correct back in the other direction. You need to check for both overshoot and undershoot cases.
This loop
while(!(Math.pow(k, value) >= n )) {
value += i;
}
goes too far. It only stops after the correct value has been surpassed. So when calculating the ones place, 1 isn't enough, so it goes to 2.0, and all subsequent tests show that it is at least enough, so that's where it ends.
Calculating logs by hand, what fun! I suggest doing it out on paper, then stepping through your code with watch variables or outputting each variable at each step. Then check this method out and see if it lines up with what you're doing: Link
You could always look at:
https://stackoverflow.com/a/2073928/251767
It provides an algorithm which will compute a log of any number in any base. It's a response to a question about calculating logs with BigDecimal
types, but it could be adapted, pretty easily, to any floating-point type.
Since it uses squaring and dividing by two, instead of using multiple calls to Math.pow()
, it should converge pretty quickly and use less CPU resources.
精彩评论