Powers of 2 can simply be computed by Bit Shift Operators
int exponent = ...
int powerOf2 = 1 << exponent;
Even for the more general form, you should not compute an exponent by "multiplying n times". Instead, you could do Exponentiation by squaring
Powers of 2 can simply be computed by Bit Shift Operators
int exponent = ...
int powerOf2 = 1 << exponent;
Even for the more general form, you should not compute an exponent by "multiplying n times". Instead, you could do Exponentiation by squaring
Here is a post that allows both negative/positive power calculations.
https://stackoverflow.com/a/23003962/3538289
Function to handle +/- exponents with O(log(n)) complexity.
double power(double x, int n){
if(n==0)
return 1;
if(n<0){
x = 1.0/x;
n = -n;
}
double ret = power(x,n/2);
ret = ret * ret;
if(n%2!=0)
ret = ret * x;
return ret;
}
Videos
When it's a power of 2 keep in mind that you can use a simple and fast shift expression: 1 << exponent
For example:
22 = 1 << 2 = (int) Math.pow(2, 2)
210 = 1 << 10 = (int) Math.pow(2, 10)
For larger exponents (over 31) use long instead:
232 = 1L << 32 = (long) Math.pow(2, 32)
BTW, in Kotlin you have shl instead of <<:
(Java) 1L << 32 = 1L shl 32 (Kotlin)
Integers are only 32 bits. This means that its max value is 2^31 -1. As you see, for very small numbers, you quickly have a result which can't be represented by an integer anymore. That's why Math.pow uses double.
If you want arbitrary integer precision, use BigInteger.pow. But it's of course less efficient.
I've been asked to create a method that takes two numbers, one for the base and one for the exponent, and then calculate and return the result. How can I go about this without utilizing the Math.pow() ?
What you are asked for is to check if the number passed as an argument to the function is a power of 2, and if it is, what is the power of 2 that sums up to aNumber. (2^x = aNumber) - you want to find x.
For example if you pass 8 to the function, you should return 3, since 2^3 = 8. But if the number isn't the power of 2, you should return -1 - for example if the parameter is 9, there is no integral power of 2 that can result in 9.
Regarding your program, you can make it work with some minor modifications:
What you want to do is make a loop and in every iteration check if the input number is dividable by 2 (aNumber % 2 == 0), and if it is divide it by two (aNumber = aNumber / 2). If you can get to 1 in this way, that means that your number is a power of two, and you just have to count the iterations (number of times you divided aNumber by 2). So your function might look like this:
private static int powerOf2(int aNumber)
{
int power = 0;
if(aNumber % 2 != 0)
{
return -1;
}
else
{
System.out.print(aNumber + " is 2 raised to ");
while (true)
{
if(aNumber % 2 == 0){
aNumber /= 2;
power++;
if(aNumber == 1) return power;
}else{
return -1;
}
}
}
}
Power of 2 means you can get the number by multiplying digit 2, for example:
If the input is 1, then you should return 0 since 20 = 1;
If the input is 2, then you should return 1 since 21 = 2 * 1 = 2;
If the input is 4, then you should return 2 since 22 = 2 * 2 = 4;
If the input is 8, then you should return 2 since 23 = 2 * 2 * 2 = 8;
...
If the input is 0 or negative, you should return -1;
If the input is not a power of 2(for example 3, 5, 7, 10), you should return -1;
The case with b<0 only makes sense with floating point numbers, so I changed the type of a and the return value to double.
public static double mathPower(double a, int b)
{
double result = 1;
if (b < 0) {
a = 1.0 / a;
b = -b;
}
for (int i = 0; i < b; i++) {
result = result * a;
}
return result;
}
You have three main problems:
The
returnstatement inside the loop is breaking it in the first repetition.You're using your
avariable as the loop variable.If you allow negative exponents then the return value should be a double.
public static double mathPower(double a, int b)
{
double result = 1.0;
if (b == 0)
{
result = 1.0;
}
if (b < 0)
{
a = (1.0 / a);
b = -b;
}
for (int i = 0; i < b; i++)
{
result = result * a;
}
return result;
}
First, observe that pow(a,x) = exp(x * log(a)).
You can implement your own exp() function using the Taylor series expansion for ex:
ex = 1 + x + x2/2! + x3/3! + x4/4! + x5/5! + ...
This will work for non-integer values of x. The more terms you include, the more accurate the result will be.
Note that by using some algebraic identities, you only need to resort to the series expansion for x in the range 0 < x < 1 . exp(int + frac) = exp(int)*exp(frac), and there's no need to use a series expansion for exp(int). (You just multiply it out, since it's an integer power of e=2.71828...).
Similarly, you can implement log(x) using one of these series expansions:
log(1+x) = x - x2/2 + x3/3 - x4/4 + ...
or
log(1-x) = -1 * (x + x2/2 + x3/3 + x4/4 + ... )
But these series only converge for x in the interval -1 < x < 1. So for values of a outside this range, you might have to use the identity
log(pq) = log(p) + log(q)
and do some repeated divisions by e (= 2.71828...) to bring a down into a range where the series expansion converges. For example, if a=4, you'd have to take take x=3 to use the first formula, but 3 is outside the range of convergence. So we start dividing out factors of e:
4/e = 1.47151...
log(4) = log(e*1.47151...) = 1 + log(1.47151...)
Now we can take x=.47151..., which is within the range of convergence, and evaluate log(1+x) using the series expansion.
Think about what a power function should do.
Mathematically: x^5 = x * x * x * x * x, or ((((x*x)*x)*x)*x)
Within your for loop, you can use the *= operator to achieve the operation that happens above.
How are you handling fractions? Java has no built-in fraction type; it stores decimals that would calculate the same way as integers (in other words, x * x works with both types). If you have a special class for fractions, your loop just needs two steps: one to multiply the numerator and one to multiply the denominator.
I've been trying to calculate the Xn without using math.pow in order to compare it with other algorithms to test their performance and math.pow is too optimized so it will impede me to compare it successfully with other algorithms:
I will use the Xn method to use it within a bruteforce method that evaluates a polynomial at x.
This method will be compared with my horners method.
If I do it using math.pow(x,n) the bruteforce will be faster than horners sometimes and I presume that its because math.pow being too fast.
Here are both method to compare, can you shed some light on why sometimes bruteforce is faster than horners, is it because of math.pow?
//Metodo de Horner:
public double horners(int[] coef_array, double x) {
double resultado = 0;
int c = 0;
for (int i = coef_array.length - 1; i >= 0; i--) {
resultado = (resultado * x) + coef_array[i];
c++;
} //Evalua en x;
set_cant_mult_H(c);
return resultado;
}
//Metodo "obvio", "a pie" o "bruteforceado":
public double brute(int[] coef_array, double x) {
double resultado = 0;
int c = 0;
for (int i = coef_array.length - 1; i >= 0; i--) {
c++;
resultado += coef_array[i] * Math.pow(x, i); // Change this mathpow with something slower?!
}
set_cant_mult_BF(c);
return resultado;
} So to wrap it off, Horners bruteforce are compared but sometimes horners is slower than bruteforce and I presume its because math.pow(x,n) is too fast.
Remember I am using arrays so maybe the new pow method may need to receive an array!
You are considering if n is negative in the n % 2 != 0 case, but not in the else case. To make it clearer, I would handle it in a different recursive case. Take the negative n handling out of the if block, and add this line after the if(n == 0) line.
if (n < 0) return 1 / myPow(x, -n);
This also eliminates the integer division you were doing in this line: return (1 / t * t * x);. It also had the error that you would have divided by t, multiplied by t, then multiplied by x, instead of dividing by the entire product.
Found this to be faster at higher powers than your solution:
public static double posIntPow(final double pVal, final int pPow) {
double ret = 1;
double v1, v2;
int n = pPow;
v1 = pVal;
if ((n & 1) == 1) {
ret = pVal;
}
n = n >>> 1;
while (n > 0) {
v2 = v1 * v1;
if ((n & 1) == 1) {
ret = ret * v2;
}
v1 = v2;
n = n >>> 1;
}
return ret;
}
And about 10 times faster than the normal Math lib one - though this obviously only does integer. Can use same test you used for negative.
Trying to figure out how to get started with this practice problem in this textbook. Not asking for code solution just some direction on where to begin. Imo (and in the opinion of other reviewers) the textbook does not include many examples for solving problems before giving practice problems, and is generally quite wordy and the authors seem to suffer from the having-a-higher-knowledge-bias-about-something and not being able to teach it as simply as possible.
I am guessing to start with importing the Math method "static double pow(double, double)", which returns the value of the first argument raised to the power of the second argument