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.
Related
Assignment:
Write a recursive function recPow that computes 2n for n >= 0 in Java. The function will have the following profile:
public static int recPow(int n)
The function must consider all cases and be tested exhaustively.
My Problem
I don't understand why my code returns -2147483648 when I enter recPow(31) instead of 2147483648. I know some of you might tell me to switch to long instead of int, but I believe due to the assignment's verbiage I need to stick with int. I have never been very good computing numbers if any one can help me understand why this happens I would truly, greatly appreciate it.
Additionally - larger exponents return 0 (however I think this may have to do with the fact that we need to use ints vs longs.)
My Code
public static int baseNum = 2, powResult = 1;
public static int recPow(int n) {
//if the int is not bigger than 0
//must only accept ints
if (n < 0) {
throw new IllegalArgumentException("n has to be > 0");
} else {
//recursion here
//base number = 2
if (n==0) {
return powResult;
} else {
powResult = powResult * baseNum;
return recPow(n - 1);
}
}
}
This is due to overflow of the int data type.
Java's int size is 32 bits, so the range is -2,147,483,648 to 2,147,483,647.
2^31 = 2147483648
So it is overflowing to -2147483648
as the binary value of 2,147,483,647 is 01111111111111111111111111111111 (one zero and 31 ones), where the first bit is the "sign bit" (2's complement form).
If you try to go beyond this limit (2,147,483,647) by 1 (i.e. adding 1 to it), it changes the sign bit to 1, making this int negative.
So it will become 10000000000000000000000000000000 (1 one and 31 zeros), giving you the answer -2147483648.
larger exponents return 0 (however I think this may have to do with the fact that we need to use ints vs longs.)
Correct.
int i = (int) 2147483648L; // -2147483648 due to over flow
int j = i * 2; // 0 due to overflow.
You can use long however this has the same problem but for a higher value.
public static long recPower(int baseNum, int power) {
if (power < 0) throw new IllegalArgumentException();
return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);
}
One way to check for an overflow is to see
public static long recPower(int baseNum, int power) {
if (power < 0) throw new IllegalArgumentException();
return power == 0 ? 1L : baseNum * recPower(baseNum, power - 1);
}
or to check for overflow
public static long recPower(int baseNum, int power) {
if (power < 0) throw new IllegalArgumentException();
return power == 0 ? 1L
: Math.multiplyExact(baseNum, recPower(baseNum, power - 1));
}
You can use BigInteger which has a much, much greater limit.
This question already has answers here:
How to check if a number is a power of 2
(32 answers)
Closed 7 years ago.
public class test{
public static void main(String[] args) {
int a=536870912;
System.out.print((Math.log(a)/Math.log(2)));
}
}
536870912 is a number that is power of two, but the result is 29.000000000000004, could anybody explain this? Thanks.
If n is a power of 2, then its binary representation will start with 1 and will contain only 0s after it.
So, you can do:
String binary = Integer.toBinaryString(a);
Pattern powerOfTwoPattern = Pattern.compile("10*");
System.out.println(powerOfTwoPattern.matcher(binary).matches());
Anyway, if you number is not really huge (i.e. fits the int or long range), then you can follow the suggestions here
You can use below method:-
boolean isPowerOfTwo (int x)
{
while (((x % 2) == 0) && x > 1) /* While x is even and > 1 */
x /= 2;
return (x == 1);
}
Explanation:- Repeatedly divides x by 2. It divides until either the quotient becomes 1, in which case x is a power of two, or the quotient becomes odd before reaching 1, in which case x is not a power of two.
pseudo-code following, easily adapted to java
boolean is_power_of_two(int num)
{
int i = Math.ceil(Math.log(num)/Math.log(2.0));
/*while ( i >= 0 )
{
// note 1 is taken as power of 2, i.e 2 ^ 0
// chnage i > 0 above to avoid this
if ( num == (1 << i) ) return true;
i--;
}
return false;*/
// or even this, since i is initialised in maximum power of two that num can have
return (num == (1 << i)) || (num == (1 << (i-1)));
}
NOTE it also can be done with discrete logarithm in constant-time without compiling to string represenation etc, but needs a precomputed table of discrete logarithms for base 2 or even using binary manipulation as in https://stackoverflow.com/a/600306/3591273, these approaches are constant-time but use the default representation of machine int or long
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.
I am implementing a pow function in Java, and I am wondering how do we deal with Integer.MIN_VALUE as a exponent ? Do we just treat it as a special case ?
Because I tried to compare the result with the standard Java.lang.Math API and I get a couple different result. The following is the list of comparison
//this will print "1.0 vs 0.0"
System.out.println(pow(2,Integer.MIN_VALUE) + " vs " + Math.pow(2,Integer.MIN_VALUE));
//this will print "1.0 vs 1.0"
System.out.println(pow(1,Integer.MIN_VALUE) + " vs " + Math.pow(1,Integer.MIN_VALUE));
public double pow(double base, int exp){
double result = 1.0;
boolean pos = false;
if(exp == 0) return result;
if(exp > 0){
pos = true;
exp *= -1;
}
while(exp > 0){
if((exp & 1) == 1){
result *= base;
}
base *= base;
exp /= 2;
}
if(!pos){
result = 1/result;
}
return result;
}
So I am wondering if Integer.MIN_VALUE is a special case where I have to have a if statement for checking it.
if(exp == Integer.MIN_VALUE && base > 1) return 0.0;
Based on this line:
exp *= -1;
it seems that it might have to be a special case. There are certainly ways to implement this without that special case, but because -1 * Integer.MIN_VALUE cannot be stored in an int, you will get a bug if you do not handle it separately.
Yeah, you've got the problem that Integer.MIN_VALUE * -1 == Integer.MIN_VALUE. You could either special-case it, or you could deal with it another way. Indeed, one possible solution would be to make exp negative when it's positive, instead of the other way around; you'd just use -exp instead of exp.
On my system I have
-2147483648
2147483647
For Integer.MIN_VALUE and Integer.MAX_VALUE respectively. So you should see the problem in the line
exp *= -1;
Well, the real issue is that, since the sign doesn't flip on the MIN_VALUE, the sign cascades to the exp/2. and the 'negative power' case applies. If we split it, it's easier:
public double myPow(double x, int n) {
double result = 1.00000;
boolean negative = false;
if(n <0) {
negative = true;
n= -n;
}
result=power(x,n);
if(negative) {
result = 1/result;
}
return result;
}
private double power(double a, int n) {
if(n ==0 || a==1) return 1;// a^0 = 1, 1^n = 1
double x=power(a,n/2);
if(n%2 == 0) return x*x;
else return a*x*x;
}
As an example in pseudocode:
if ((a mod 2) == 0)
{
isEven = true;
}
else
{
isEven = false;
}
Instead of the modulo operator, which has slightly different semantics, for non-negative integers, you can use the remainder operator %. For your exact example:
if ((a % 2) == 0)
{
isEven = true;
}
else
{
isEven = false;
}
This can be simplified to a one-liner:
isEven = (a % 2) == 0;
Here is the representation of your pseudo-code in minimal Java code;
boolean isEven = a % 2 == 0;
I'll now break it down into its components. The modulus operator in Java is the percent character (%). Therefore taking an int % int returns another int. The double equals (==) operator is used to compare values, such as a pair of ints and returns a boolean. This is then assigned to the boolean variable 'isEven'. Based on operator precedence the modulus will be evaluated before the comparison.
Since everyone else already gave the answer, I'll add a bit of additional context. % the "modulus" operator is actually performing the remainder operation. The difference between mod and rem is subtle, but important.
(-1 mod 2) would normally give 1. More specifically given two integers, X and Y, the operation (X mod Y) tends to return a value in the range [0, Y). Said differently, the modulus of X and Y is always greater than or equal to zero, and less than Y.
Performing the same operation with the "%" or rem operator maintains the sign of the X value. If X is negative you get a result in the range (-Y, 0]. If X is positive you get a result in the range [0, Y).
Often this subtle distinction doesn't matter. Going back to your code question, though, there are multiple ways of solving for "evenness".
The first approach is good for beginners, because it is especially verbose.
// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
isEven = true
}
else
{
isEven = false
}
The second approach takes better advantage of the language, and leads to more succinct code. (Don't forget that the == operator returns a boolean.)
// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);
The third approach is here for completeness, and uses the ternary operator. Although the ternary operator is often very useful, in this case I consider the second approach superior.
// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;
The fourth and final approach is to use knowledge of the binary representation of integers. If the least significant bit is 0 then the number is even. This can be checked using the bitwise-and operator (&). While this approach is the fastest (you are doing simple bit masking instead of division), it is perhaps a little advanced/complicated for a beginner.
// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);
Here I used the bitwise-and operator, and represented it in the succinct form shown in option 2. Rewriting it in Option 1's form (and alternatively Option 3's) is left as an exercise to the reader. ;)
To get Java's % (REM) operation to work like MOD for negative X and positive Y values, you can use this method:
private int mod(int x, int y)
{
int result = x % y;
if (result < 0)
{
result += y;
}
return result;
}
or with the ternary operator (shorter, but not possible or less efficient in some situations):
private int mod(int x, int y)
{
int result = x % y;
return result < 0? result + y : result;
}
Java actually has no modulo operator the way C does. % in Java is a remainder operator. On positive integers, it works exactly like modulo, but it works differently on negative integers and, unlike modulo, can work with floating point numbers as well. Still, it's rare to use % on anything but positive integers, so if you want to call it a modulo, then feel free!
While it's possible to do a proper modulo by checking whether the value is negative and correct it if it is (the way many have suggested), there is a more compact solution.
(a % b + b) % b
This will first do the modulo, limiting the value to the -b -> +b range and then add b in order to ensure that the value is positive, letting the next modulo limit it to the 0 -> b range.
Note: If b is negative, the result will also be negative
The code runs much faster without using modulo:
public boolean isEven(int a){
return ( (a & 1) == 0 );
}
public boolean isOdd(int a){
return ( (a & 1) == 1 );
}
In Java it is the % operator:
15.17.3. Remainder Operator %
Note that there is also floorMod in the java.lang.Math class which will give a different result from % for arguments with different signs:
public static int floorMod​(int x, int y)
As others have pointed out, the % (remainder) operator is not the same as the mathematical
mod modulus operation/function.
mod vs %
The x mod n function maps x to n in the range of [0,n).
Whereas the x % n operator maps x to n in the range of (-n,n).
In order to have a method to use the mathematical modulus operation and not
care about the sign in front of x one can use:
((x % n) + n) % n
Maybe this picture helps understand it better (I had a hard time wrapping my head around this first)
if (a % 2 == 0) {
} else {
}
you should examine the specification before using 'remainder' operator % :
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.17.3
// bad enough implementation of isEven method, for fun. so any worse?
boolean isEven(int num)
{
num %= 10;
if(num == 1)
return false;
else if(num == 0)
return true;
else
return isEven(num + 2);
}
isEven = isEven(a);
Also, mod can be used like this:
int a = 7;
b = a % 2;
b would equal 1. Because 7 % 2 = 1.
The remainder operator in Java is % and the modulo operator can be expressed as
public int mod(int i, int j)
{
int rem = i % j;
if (j < 0 && rem > 0)
{
return rem + j;
}
if (j > 0 && rem < 0)
{
return rem + j;
}
return rem;
}
In Java, the mod operation can be performed as such:
Math.floorMod(a, b)
Note:
The mod operation is different from the remainder operation. In Java, the remainder operation can be performed as such:
a % b
Another way is:
boolean isEven = false;
if((a % 2) == 0)
{
isEven = true;
}
But easiest way is still:
boolean isEven = (a % 2) == 0;
Like #Steve Kuo said.
The modulo operator is % (percent sign). To test for evenness or generally do modulo for a power of 2, you can also use & (the and operator) like isEven = !( a & 1 ).
An alternative to the code from #Cody:
Using the modulus operator:
bool isEven = (a % 2) == 0;
I think this is marginally better code than writing if/else, because there is less duplication & unused flexibility. It does require a bit more brain power to examine, but the good naming of isEven compensates.