I am trying to write a code that computes the following for a given integer n:
1/1 + 1/2 + 1/3 ... + 1/n
This is the code I have written so far:
public class RecursiveSum
{
public static double Sumto(int n)
{
if (n == 0) { return 0.0; }
else if (n > 0) { return 1/n + 1/Sumto(n - 1); }
else { throw new IllegalArgumentException("Please provide positive integers"); }
}
public static void main(String[] args)
{
System.out.println(Sumto(5));
}
}
However, it always outputs:
Infinity
What is the problem and how can I fix it?
Thank you
You have two issues :
You must perform floating point division (i.e. replace 1/n with 1.0/n), and you should add Sumto(n - 1) to 1.0/n to get Sumto(n).
public static double Sumto(int n)
{
if (n == 0) { return 0.0; }
else if (n > 0) { return 1.0/n + Sumto(n - 1); }
else { throw new IllegalArgumentException("Please provide positive integers"); }
}
The reason you got Infinity was that 1/Sumto(n - 1) returns Infinity when Sumto(n - 1) is 0.0, and Sumto(0) is 0.0.
However, it always outputs: Infinity
Because you are doing 1/0 in the following steps in your code which yields Infinity.
else if (n > 0) { return 1/n + 1/Sumto(n - 1);
You thought n > 0 escapes the n / 0 stuffs, but nope! Think about the case when n = 1 which passes n > 0 case but fall into a trap to:
1/Sumto(n - 1)
1/Sumto(1 - 1)
1/Sumto(0)
where Sumto(0) returns 0.0. Hence,
1/0.0
yields Infinity. Moreover, use 1.0/n instead of 1/n as it is floating point division.
So add another condition, like
if(n == 1)
return 1;
A few problems, nothing first that since there is no closed form expression for the harmonic series.
You need to compute each term using floating point division. Rewrite as 1.0 / n.
Drop the term 1.0 / 0 as that will give you an infinite floating point value.
You'll get better accuracy if you reverse the loop. That is, compute the smaller terms first. Otherwise you'll underestimate the sum with floating point arithmetic. As a rule of thumb, always add small numbers first.
Related
I was trying to use java's integer division, and it supposedly takes the floor. However, it rounds towards zero instead of the floor.
public class Main {
public static void main(String[] args) {
System.out.println(-1 / 100); // should be -1, but is 0
System.out.println(Math.floor(-1d/100d)); // correct
}
}
The problem is that I do not want to convert to a double/float because it needs to be efficient. I'm trying to solve this with a method, floorDivide(long a, long b). What I have is:
static long floorDivide(long a, long b) {
if (a < 0) {
// what do I put here?
}
return a / b;
}
How can I do this without a double/float?
floorDiv() from Java.Math that does exactly what you want.
static long floorDiv(long x, long y)
Returns the largest (closest to positive infinity) long value that is less than or equal to the algebraic quotient.
Take the absolute value, divide it, multiply it by -1.
Weird bug.
You can use
int i = (int) Math.round(doubleValToRound);
It will return a double value that you can cast into an int without lost of precission and without performance problems (casts haven't a great computational cost)
Also it's equivalent to
int a = (int) (doubleValToRound + 0.5);
//in your case
System.out.println((int) ((-1 / 100) + 0.5));
With this last one you won't have to enter into tedious and unnecesary "if" instructions. Like a good suit, its valid for every moment and has a higher portability for other languages.
This is ugly, but meets the requirement to not use a double/float. Really you should just cast it to a double.
The logic here is take the floor of a negative result from the integer division if it doesn't divide evenly.
static long floorDivide(long a, long b)
{
if(a % b != 0 && ((a < 0 && b > 0) || (a > 0 && b < 0)))
{
return (a / b - 1);
}
else
{
return (a / b);
}
}
Just divide the two integers. then add -1 to the result (in case the absolute value of both numerator and denominator are not same). For example -3/3 gives you -1, the right answer without adding -1 to the division.
Since a bit late, but you need to convert your parameters to long or double
int result = (int) Math.floor( (double) -1 / 5 );
// result == -1
This worked for me elegantly.
I would use floorDiv() for a general case, as Frank Harper suggested.
Note, however, that when the divisor is a power of 2, the division is often substituted by a right shift by an appropriate number of bits, i.e.
x / d
is the same as
x >> p
when p = 0,1,...,30 (or 0,1,...,62 for longs), d = 2p and x is non-negative. This is not only more effective than ordinary division but gives the right result (in mathematical sense) when x is negative.
I know that java.lang.Math provides a set of static methods to perform some operations (sum, difference, multiply, increment, decrement, negate, toInt), throwing an ArithmeticException on overflow.
Is there something similar for power?
No, there is nothing equivalent for pow built into Java. (The only pow methods built into Java are Math.pow, which accepts doubles and does not overflow in the same way integers do, and BigInteger.pow, which does not overflow because BigIntegers can be arbitrarily large.)
If third-party libraries are acceptable, though, Guava has e.g. IntMath.checkedPow, which does what you're looking for.
As Chirag said, integers throw exceptions when they overflow while doubles don't. Not to get too specific but, basically, doubles in memory are stored very similarly to scientific notation, in that they are some integer * 2^(some power), and thus never really overflow but multiply by such a large or small 2^(some power) that they completely lose their precision. So you can instead think of double overflow as when they completely lose their precision and are printed as either Infinity or -Infinity.
So, you will need to manually check that an overflow has occurred by checking if the resulting value is Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY.
Here is some sample code to show what I mean:
public static void main(String[] args) throws Exception
{
double a = Double.MAX_VALUE; // highest possible double
double b = Double.MAX_VALUE; // highest possible double
if (Math.pow(a, b) == Double.POSITIVE_INFINITY || Math.pow(a, b) == Double.NEGATIVE_INFINITY)
{
throw new ArithmeticException("Double Overflow");
}
}
If it's fine to have your own implementation, you could do something like this:
private static final int[] maxBaseForExponent = IntStream.range(0, 30)
.map(e -> (int) Math.pow(Integer.MAX_VALUE, 1d / e)).toArray();
public static int powExact(int base, int exponent) {
if (exponent < 0) {
throw new ArithmeticException("Negative exponent");
}
if ((base < -1 || base > 1) && (exponent > 30 || base > maxBaseForExponent[exponent])
&& !(base == -2 && exponent == 31)) {
throw new ArithmeticException("Overflow");
}
switch (base) {
case -2:
return (exponent & 1) == 0 ? 1 << exponent : -1 << exponent;
case -1:
return (exponent & 1) == 0 ? 1 : -1;
case 0:
return exponent == 0 ? 1 : 0;
case 1:
return 1;
case 2:
return 1 << exponent;
default:
}
int result = 1;
while (exponent != 0) {
if ((exponent & 1) != 0) {
result *= base;
}
exponent >>= 1;
base *= base;
}
return result;
}
Took the algorithm from here, and modified it to check for overflow using an array which contains max base for each exponent from 0 to 30.
Integers are only 32 bits. so max value is 2^31 -1. ( If using BigInteger.pow. It is less efficient.)
So you can check manually and throw Exception if required
else use Math.pow which uses double.
I'm trying to write a function to determine whether a number is "ugly". For a number to be "ugly", it must have no prime factors other than 2, 3, or 5.
Here's my attempt:
public class Solution {
public boolean isPrime(int num) {
if (num == 2) {
return true;
}
if (num % 2 == 0) {
return false;
}
if (num < 0) {
num *= -1;
}
for (int i = 3; i <= Math.sqrt(num); i += 2) {
if (num % i == 0) {
return false;
}
}
return true;
}
public boolean isUgly(int num) {
if (num < 0) {
num *= -1;
}
for (int i = 7; i <= Math.sqrt(num); i += 2) {
if ((num % i == 0) && isPrime(num)) {
return false;
}
}
return true;
}
}
I'm getting true for input = -2147483648 when it should be false. Is it possible there's an overflow here? I've gone over my code and the logic looks right to me...
Thanks!
The problem is Integer.MIN_VALUE*-1 = Integer.MIN_VALUE leading to Math.sqrt(Integer.MIN_VALUE) which returns NaN on a negative number, so then when you perform this operation 7 <= Math.sqrt(Integer.MIN_VALUE) it returns false and doesn't even enter the for loop resulting in the program returning true.
I hope this explanation helps.
Yeah, I guess so.
Java lower limit for int is -2147483648 and upper 2147483647. As shown in
public class MainClass {
public static void main(String[] arg) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
Negative numbers are tricky in such a question.
You have to take the absolute number and factor it. In your original source, you didn't do this. It meant that you got a NaN from the Math.sqrt method. Which also meant that you got false when you compared it to 7.
So your original method would have returned true for all negative numbers.
But changing the sign (which, by the way can be done by num = -num rather than multiplication), which would solve it for all negative numbers, actually introduced an overflow into the program.
The number -2147483648 is, in fact, -231. The maximum positive number allowed in an int is 231-1. So the number - Integer.MIN_VALUE always overflows... into itself. It remains negative after you negate it!
So you run into that NaN again.
But note - since the number is -231, it doesn't, in fact, have any other prime factors other than 2. So the method really should return true for it - assuming that you are not considering -1 a prime.
So I believe that your expectation that it should be false is incorrect - but it depends on the assignment's definition of the prime factors of negative numbers.
Notes:
Your program checks isPrime(num) instead of isPrime(i), and therefore it will always return true. num cannot both be divisible by i and be prime at the same time.
Limiting your program to the square root of num is wrong to begin with. For example, take the number 881305274. Its prime factors are 2 and 440652637. But 440652637 is much bigger than sqrt(881305274). The square root trick works for prime testing, because any factor that is bigger than the root has to be multiplied by a factor that's smaller than the root. But this doesn't apply to the "ugly" problem.
Also, prime numbers are not considered "ugly" as they are a factor of themselves. But your program, because it limits itself to the square root, will never return false for prime numbers.
I have to write a power method in Java. It receives two ints and it doesn't matter if they are positive or negative numbers. It should have complexity of O(logN). It also must use recursion. My current code gets two numbers but the result I keep outputting is zero, and I can't figure out why.
import java.util.Scanner;
public class Powers {
public static void main(String[] args) {
float a;
float n;
float res;
Scanner in = new Scanner(System.in);
System.out.print("Enter int a ");
a = in.nextFloat();
System.out.print("Enter int n ");
n = in.nextFloat();
res = powers.pow(a, n);
System.out.print(res);
}
public static float pow(float a, float n) {
float result = 0;
if (n == 0) {
return 1;
} else if (n < 0) {
result = result * pow(a, n + 1);
} else if (n > 0) {
result = result * pow(a, n - 1);
}
return result;
}
}
Let's start with some math facts:
For a positive n, aⁿ = a⨯a⨯…⨯a n times
For a negative n, aⁿ = ⅟a⁻ⁿ = ⅟(a⨯a⨯…⨯a). This means a cannot be zero.
For n = 0, aⁿ = 1, even if a is zero or negative.
So let's start from the positive n case, and work from there.
Since we want our solution to be recursive, we have to find a way to define aⁿ based on a smaller n, and work from there. The usual way people think of recursion is to try to find a solution for n-1, and work from there.
And indeed, since it's mathematically true that aⁿ = a⨯(aⁿ⁻¹), the naive approach would be very similar to what you created:
public static int pow( int a, int n) {
if ( n == 0 ) {
return 1;
}
return ( a * pow(a,n-1));
}
However, the complexity of this is O(n). Why? Because For n=0 it doesn't do any multiplications. For n=1, it does one multiplication. For n=2, it calls pow(a,1) which we know is one multiplication, and multiplies it once, so we have two multiplications. There is one multiplication in every recursion step, and there are n steps. So It's O(n).
In order to make this O(log n), we need every step to be applied to a fraction of n rather than just n-1. Here again, there is a math fact that can help us: an₁+n₂ = an₁⨯an₂.
This means that we can calculate aⁿ as an/2⨯an/2.
But what happens if n is odd? something like a⁹ will be a4.5⨯a4.5. But we are talking about integer powers here. Handling fractions is a whole different thing. Luckily, we can just formulate that as a⨯a⁴⨯a⁴.
So, for an even number use an/2⨯an/2, and for an odd number, use a⨯ an/2⨯an/2 (integer division, giving us 9/2 = 4).
public static int pow( int a, int n) {
if ( n == 0 ) {
return 1;
}
if ( n % 2 == 1 ) {
// Odd n
return a * pow( a, n/2 ) * pow(a, n/2 );
} else {
// Even n
return pow( a, n/2 ) * pow( a, n/2 );
}
}
This actually gives us the right results (for a positive n, that is). But in fact, the complexity here is, again, O(n) rather than O(log n). Why? Because we're calculating the powers twice. Meaning that we actually call it 4 times at the next level, 8 times at the next level, and so on. The number of recursion steps is exponential, so this cancels out with the supposed saving that we did by dividing n by two.
But in fact, only a small correction is needed:
public static int pow( int a, int n) {
if ( n == 0 ) {
return 1;
}
int powerOfHalfN = pow( a, n/2 );
if ( n % 2 == 1 ) {
// Odd n
return a * powerOfHalfN * powerOfHalfN;
} else {
// Even n
return powerOfHalfN * powerOfHalfN;
}
}
In this version, we are calling the recursion only once. So we get from, say, a power of 64, very quickly through 32, 16, 8, 4, 2, 1 and done. Only one or two multiplications at each step, and there are only six steps. This is O(log n).
The conclusion from all this is:
To get an O(log n), we need recursion that works on a fraction of n at each step rather than just n - 1 or n - anything.
But the fraction is only part of the story. We need to be careful not to call the recursion more than once, because using several recursive calls in one step creates exponential complexity that cancels out with using a fraction of n.
Finally, we are ready to take care of the negative numbers. We simply have to get the reciprocal ⅟a⁻ⁿ. There are two important things to notice:
Don't allow division by zero. That is, if you got a=0, you should not perform the calculation. In Java, we throw an exception in such a case. The most appropriate ready-made exception is IllegalArgumentException. It's a RuntimeException, so you don't need to add a throws clause to your method. It would be good if you either caught it or prevented such a situation from happening, in your main method when you read in the arguments.
You can't return an integer anymore (in fact, we should have used long, because we run into integer overflow for pretty low powers with int) - because the result may be fractional.
So we define the method so that it returns double. Which means we also have to fix the type of powerOfHalfN. And here is the result:
public static double pow(int a, int n) {
if (n == 0) {
return 1.0;
}
if (n < 0) {
// Negative power.
if (a == 0) {
throw new IllegalArgumentException(
"It's impossible to raise 0 to the power of a negative number");
}
return 1 / pow(a, -n);
} else {
// Positive power
double powerOfHalfN = pow(a, n / 2);
if (n % 2 == 1) {
// Odd n
return a * powerOfHalfN * powerOfHalfN;
} else {
// Even n
return powerOfHalfN * powerOfHalfN;
}
}
}
Note that the part that handles a negative n is only used in the top level of the recursion. Once we call pow() recursively, it's always with positive numbers and the sign doesn't change until it reaches 0.
That should be an adequate solution to your exercise. However, personally I don't like the if there at the end, so here is another version. Can you tell why this is doing the same?
public static double pow(int a, int n) {
if (n == 0) {
return 1.0;
}
if (n < 0) {
// Negative power.
if (a == 0) {
throw new IllegalArgumentException(
"It's impossible to raise 0 to the power of a negative number");
}
return 1 / pow(a, -n);
} else {
// Positive power
double powerOfHalfN = pow(a, n / 2);
double[] factor = { 1, a };
return factor[n % 2] * powerOfHalfN * powerOfHalfN;
}
}
pay attention to :
float result = 0;
and
result = result * pow( a, n+1);
That's why you got a zero result.
And instead it's suggested to work like this:
result = a * pow( a, n+1);
Beside the error of initializing result to 0, there are some other issues :
Your calculation for negative n is wrong. Remember that a^n == 1/(a^(-n)).
If n is not integer, the calculation is much more complicated and you don't support it. I won't be surprised if you are not required to support it.
In order to achieve O(log n) performance, you should use a divide and conquer strategy. i.e. a^n == a^(n/2)*a^(n/2).
Here is a much less confusing way of doing it, at least if your not worred about the extra multiplications. :
public static double pow(int base,int exponent) {
if (exponent == 0) {
return 1;
}
if (exponent < 0) {
return 1 / pow(base, -exponent);
}
else {
double results = base * pow(base, exponent - 1);
return results;
}
}
# a pow n = a pow n%2 * square(a) pow(n//2)
# a pow -n = (1/a) pow n
from math import inf
def powofn(a, n):
if n == 0:
return 1
elif n == 1:
return a
elif n < 0:
if a == 0 : return inf
return powofn(1/a, -n)
else:
return powofn(a, n%2) * powofn(a*a, n//2)
A good rule is to get away from the keyboard until the algorythm is ready. What you did is obviously O(n).
As Eran suggested, to get a O(log(n)) complexity, you have to divide n by 2 at each iteration.
End conditions :
n == 0 => 1
n == 1 => a
Special case :
n < 0 => 1. / pow(a, -n) // note the 1. to get a double ...
Normal case :
m = n /2
result = pow(a, n)
result = resul * resul // avoid to compute twice
if n is odd (n % 2 != 0) => resul *= a
This algorythm is in O(log(n)) - It's up to you to write correct java code from it
But as you were told : n must be integer (negative of positive ok, but integer)
import java.io.*;
import java.util.*;
public class CandidateCode {
public static void main(String args[] ) throws Exception {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc. nextInt();
int result = power(m,n);
System.out.println(result);
}
public static int power(int m, int n){
if(n!=0)
return (m*power(m,n-1));
else
return 1;
}
}
try this:
public int powerN(int base, int n) {return n == 0 ? 1 : (n == 1 ? base : base*(powerN(base,n-1)));
ohk i read solutions of others posted her but let me clear you those answers have given you
the correct & optimised solution but your solution can also works by replacing float result=0 to float result =1.
I'm trying to count the number of Ones in the binary representation of an integer. I need to do this recursively. I think my logic is correct but I continue to get a stack overflow. I'm on day 2 troubleshooting. Here's my code:
static int CountRecursive(int n) {
int sum = 0;
if (n >= 0) {
if (n%2 == 1) {
sum ++;
} sum += CountRecursive(n/2);
} return sum;
}
My logic is based on this information: "The standard mechanism for converting from decimal to binary is to repeatedly divide the decimal number by 2 and, at each division, output the remainder (0 or 1)."
Remove the equals in the if. 0 divided by 2 is still zero - you go into infinite recursion.
I mean make this one:
if (n >= 0)
strict comparison i.e:
if (n > 0)