I have the following statement:
long result = a * b * c;
This causes an overflow in the variable result. And so does:
long result = (long)a * b * c;
But the when broken down, they don't:
long result = a;
result *= b;
result *= c;
The type of a and b is int.
Can someone please explain why this is so? Does Java store the intermediate results in a temporary internal int variable in the first two cases?
Also do C and C++ behave the same way?
Assuming a * b * c fits in a long, but a * b does not fit in an int -
Your first snippet gives an overflow because a * b goes into a temporary int, as you suspected.
Your second snippet does NOT give an overflow, as you claim, because it is multiplying long values at each point.
Your third snippet doesn't give an overflow, because it is also multiplying long values at each point.
And, yes, C and C++ both work this way too; although depending on the platform, they may have different lengths for both int and long.
See the Oracle documentation for operator precedence.
Unary has higher precedence than multiplication, so (long)a*b*c is (long)(a)*b*c.
Same in C++.
I just tested these programs:
public class JavaApplication2 {
public static void main(String[] args) {
long l = (long)Integer.MAX_VALUE;
l *= 2;
l *= 2;
System.out.println(l);
}
}
and
public class JavaApplication2 {
public static void main(String[] args) {
long l = (long)Integer.MAX_VALUE*2*2;
System.out.println(l);
}
}
They show the exact same output.
In contrast, remove the cast in the second version and you get an overflow.
Related
i tried using this.
import java.io.*; // for handling input/output
import java.util.*; // contains Collections framework
// don't change the name of this class
// you can add inner classes if needed
class Main {
public static void main (String[] args) {
Scanner s=new Scanner(System.in);
int m=1000000007;
int a=s.nextInt();
int b=s.nextInt();
int c=s.nextInt();
int d=s.nextInt();
long temp1=power(c,d)%m;
long temp2= power(b,temp1)%m;
long result=power(a,temp2)%m;
System.out.println(result);
}
public static long power(int x, long n){
int m=1000000007;
if(n==0){
return 1;
}
if(n==1){
return x;
}
if(n%2==0){
return (power(x,n/2)*power(x,n/2))%m;
}else {
return ((power(x,n/2)*power(x,n/2))%m * x)%m;
}
}
}
but problem is when i increase size of a b c d then its showing TLE.
like for a=2 b=2 c=2 d=2 its giving output 65536 but when i take a=12 b=12 c=12 d=12 output should be 322269119 but using this it is showing Time limit exceed error. anyone can explain how to do this type of qurstion where it said that output value will be large so print is after doing mod 10^9+7.
Edit: a b c d values can be different.
The TLE is due to power recursively calling itself twice per invocation, so it expands to a full binary tree of calls (size: n) instead of into a nice linear chain of calls (length: log(n)) which is how Exponentiation by Squaring is supposed to work. In other words, it's exponentially slower than it needs to be, and for a very boring reason. Easy fix:
public static long power(int x, long n){
int m=1000000007;
if(n==0){
return 1;
}
if(n==1){
return x;
}
long p = power(x,n/2);
if(n%2==0){
return p * p % m;
}else {
return (p * p % m) * x % m;
}
}
But there is also a "math bug" in your program: abcd mod n is not equivalent to a^(b^(c^d mod n) mod n) mod n. Modular addition and multiplication work that way, but exponentiation has a different kind of periodicity.
Just using big integers naively is not sufficient, 12^12^12 would be a 4TB BigInteger, even on a computer that could handle that, computing or using such a physically large number would just take too long. But you can use Euler's theorem, and compute 12^12^12 mod φ(n). 12^12 is no big deal it even fits in a long, then 12 to the power of that long can be a modexp again but modulo φ(1E9+7) which is 1E9+6. For slightly larger c and d, c^d can also be computed as a BigInteger, as long as it isn't too big.
When c or d are so large that c^d is a problem even with BigIntegers, you can use more tricks to compute b^c^d mod φ(n) without the "full" c^d. Unfortunately Euler's theorem is not applicable to the "inner" exponentiation because the GCD of the modulus and the base may not be 1 (and isn't 1 in the example with the twelves), but there is a more complex expression that works in that case.
I need to output the total number of digits before the decimal point of a float number and output the results as a short.
This is what I have so far:
public static void main(String[] args) {
DigitsBeforeDot(18.879);
}
public static short DigitsBeforeDot(float x){
short a = (short) x;
System.out.println((short)Math.log10(a)+1);
return a;
}
I get a suggestion to cast the argument in the method to a float like this:
public static void main(String[] args) {
DigitsBeforeDot((float) 18.879);
}
And this makes the program work but I need to make it work without the casting by changing something in the method.
What is the best way to do that?
Stick to naming conventions. public static short DigitsBeforeDot(float x){ should be public static short digitsBeforeDot(float x) { or even better: public static short getDigitsBeforeDot(float x) { or public static short calculateDigitsBeforeDot(float x) {
Use a source code formatter if your IDE provides one
Instead of working with float and int, go with double and long. Apart from storing values in arrays (RAM consumption) there is no downside to using the full register width (64bit) of modern platforms. The upside is that you're a lot less likely to run into problems with precision or overflows.
It's highly unlikely that you want partial/float/fractions of the number of digits (like 2.176 as a result for log10(150)). It's a lot more likely you want the integer number returned, i.e. 2. So you should use an byte/short/int/long as return value. I recommend usnig long: public static long calculateDigitsBeforeDot(double x) {, and instead of casting the log10 to a short, you just cast it to a long instead. Java always rounds towards zero, so that would equal a call to Math.floor(Math.log10(a)) + 1
Why is casting not an option for you?
Unless I'm missing something, change the signature of the method to take a double.
public static short DigitsBeforeDot(double x) {
short a = (short) (Math.log10(x) + 1);
System.out.println(a);
return a;
}
Also, it seems really counter productive to pass a float or a double only to cast to a short.
I need to find 2 to-the-power N where N is a very large number (Java BigInteger type)
Java BigInteger Class has pow method but it takes only integer value as exponent.
So, I wrote a method as follows:
static BigInteger twoToThePower(BigInteger n)
{
BigInteger result = BigInteger.valueOf(1L);
while (n.compareTo(BigInteger.valueOf((long) Integer.MAX_VALUE)) > 0)
{
result = result.shiftLeft(Integer.MAX_VALUE);
n = n.subtract(BigInteger.valueOf((long) Integer.MAX_VALUE));
}
long k = n.longValue();
result = result.shiftLeft((int) k);
return result;
}
My code works fine, I am just sharing my idea and curious to know if there is any other better idea?
Thank you.
You cannot use BigInteger to store the result of your computation. From the javadoc :
BigInteger must support values in the range -2^Integer.MAX_VALUE (exclusive) to +2^Integer.MAX_VALUE (exclusive) and may support values outside of that range.
This is the reason why the pow method takes an int. On my machine, BigInteger.ONE.shiftLeft(Integer.MAX_VALUE) throws a java.lang.ArithmeticException (message is "BigInteger would overflow supported range").
Emmanuel Lonca's answer is correct. But, by Manoj Banik's idea, I would like to share my idea too.
My code do the same thing as Manoj Banik's code in faster way. The idea is init the buffer, and put the bit 1 in to correct location. I using the shift left operator on 1 byte instead of shiftLeft method.
Here is my code:
static BigInteger twoToThePower(BigInteger n){
BigInteger eight = BigInteger.valueOf(8);
BigInteger[] devideResult = n.divideAndRemainder(eight);
BigInteger bufferSize = devideResult[0].add(BigInteger.ONE);
int offset = devideResult[1].intValue();
byte[] buffer = new byte[bufferSize.intValueExact()];
buffer[0] = (byte)(1 << offset);
return new BigInteger(1,buffer);
}
But it still slower than BigInteger.pow
Then, I found that class BigInteger has a method called setBit. It also accepts parameter type int like the pow method. Using this method is faster than BigInteger.pow.
The code can be:
static BigInteger twoToThePower(BigInteger n){
return BigInteger.ZERO.setBit(n.intValueExact());
}
Class BigInteger has a method called modPow also. But It need one more parameter. This means you should specify the modulus and your result should be smaller than this modulus. I did not do a performance test for modPow, but I think it should slower than the pow method.
By using repeated squaring you can achieve your goal. I've posted below sample code to understand the logic of repeated squaring.
static BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
while (exponent.signum() > 0) {
if (exponent.testBit(0)) result = result.multiply(base);
base = base.multiply(base);
exponent = exponent.shiftRight(1);
}
return result;
}
An interesting question. Just to add a little more information to the fine accepted answer, examining the openjdk 8 source code for BigInteger reveals that the bits are stored in an array final int[] mag;. Since arrays can contain at most Integer.MAX_VALUE elements this immediately puts a theoretical bound on this particular implementation of BigInteger of 2(32 * Integer.MAX_VALUE). So even your method of repeated left-shifting can only exceed the size of an int by at most a factor of 32.
So, are you ready to produce your own implementation of BigInteger?
EDIT:
I think my purpose was not understood, and so the negative votes and comments. I am NOT interested in knowing what bit of a floating point(double) means what, and if they match the same position in a long; this is totally irrelevant to me. My problem is the following: I want to use a single primitive array to store all my primitive values. If I choose a double[] as "storage", I need to be able to store longs in it too (I could also do it the other way around, but the problem would not go away, just be reversed). Since both are the same size, it should work, somehow. Using Double.doubleToRawLongBits(double) and Double.longBitsToDouble(long) allow me to do that. But what I wanted to know was: "Can I just put cast a long to an double and back, and always get the same long back?" If THAT is true, then it solves my problem, and I don't care if the bits gets moved around internally. So I wanted to test if I can safely safely do this. The output says all 64 bits could be accessed and modified individually, but possibly this is not sufficient to prove that no long bit gets lost/modified.
I just discovered, with a small test, that I can correctly "address" every bit in a double, just by casting to long and back. Here the test program (which succeeds, at least on Java 7 / Windows 7 64bit):
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class TestDoubleBits {
private static double set(final double d, final int bit, final boolean value) {
if (value) {
return ((long) d) | (1L << bit);
} else {
return ((long) d) & ~(1L << bit);
}
}
private static boolean get(final double d, final int bit) {
return (((long) d) & (1L << bit)) != 0;
}
#Test
public void testDoubleBits() {
final double value = Math.random();
for (int bit = 0; bit < 64; bit++) {
assertTrue((get(set(value, bit, false), bit) == false));
assertTrue((get(set(value, bit, true), bit) == true));
}
}
}
Assuming my test program correctly "proves" that every bit of a double can be accessed, just by casting to long and back, why do we have the following native methods:
Double.doubleToRawLongBits(double)
Double.longBitsToDouble(long)
Since native methods are usually slower (the content of the method might be faster, but the overhead of native call make it slower), is there any benefit to using those methods?
The bit pattern of a floating point number will NEVER (with ONE exception) remotely resemble the bit pattern of the corresponding integer value, if one exists.
I suggest you run the following program
public class Test
{
public static void main(String[] args) {
double d = 1.3;
long d1 = (long) d;
long d2 = (Double.doubleToLongBits(d));
System.out.printf("cast %016X bits %016X\n", d1, d2);
}
}
Then read What Every Computer Scientist Should Know About Floating-Point Arithmetic
(The exception is, of course, the value zero)
If you want to investigate further, there's a neat interactive floating point converter at CUNY that displays everything you'd ever want to know about any given number's float representations.
This is the test I should have used. It fails at 53, which (I assume) means that only the first 52 bits of a long could be stored in a double "safely" without using those native methods (this also precludes using any negative values).
public class TestDoubleBits {
public static void main(final String[] args) {
int failsAt = -1;
long value = 1;
for (int bit = 1; bit < 64; bit++) {
value = value | (1L << bit);
final double d = value;
final long l2 = (long) d;
if (value != l2) {
failsAt = bit;
break;
}
}
System.out.println("failsAt: " + failsAt);
value = value & ~(1L << failsAt);
System.out.println("Max value decimal: " + value);
System.out.println("Max value hex: " + Long.toHexString(value));
System.out.println("Max value binary: " + Long.toBinaryString(value));
}
}
The problem with my original test was that I tested the bits individually. By always setting the first bit to 1, I can find out when I start loosing data, because the least significant bit is the "first to go".
I was doing some stuff with palindromes:
This number 9966006699 has been giving me problems. It's a product of 99979 and 99681
99979 * 99681 = 9966006699
I ran that in PHP
$i = 99979 * 99681;
echo $i;
var_dump($i);
Outputs
9966006699 float(9966006699)
So in PHP the product is obviously a float data type. But in Java it's different as seen below :
This
public static void main(String[] args) {
float f = 99979 * 99681;
System.out.println(f);
long o = 99979 * 99681;
System.out.println(o);
double d = 99979 * 99681;
System.out.println(d);
int i = 99979 * 99681;
System.out.println(i);
}
Outputs
1.37607206E9
1376072107
1.376072107E9
1376072107
Google's calculator gives the right thing
I'm lost, why is Java giving the wrong output? and Does it have anything to do with the E9 stuff behind the float and double types? Help. Thanks
The numbers 99979 and 99681 are both int's. The multiplication expression is therefore an int expression too. The maximum value of an int expression is 2147...... Your value 9966006699 is way above that. Hence you have fallen in the realms of the strange behaviour that you get from modulo-n arithmetic. (That is, you have fallen victim to the C-family languages' version of the Y2K problem.)
Try this :
long o = (long)99979 * 99681;
System.out.println(o);
It looks like integer overflow as 9 966 006 699 > Integer.MAX_INT = 2 147 483 647. As int times int have type int the result overflows. Then it is cast to int/float/long etc.
This should be correct (for non-int):
long value = (long)99979 * (long)99681
Alternativly you can use BigInteger class which:
May be slower the using int/long
Don't have this problem for any numbers (long just moves the problem from 2^31 - 1 to 2^63-1).
Integer.MAX_VALUE is equal to 2^31-1, which is smaller than the number you're dealing with, so you're essentially getting integer overflow issues. You can get around this by using a long, or the BigInteger class.
You can read about the numeric limits of primitive data types here:
http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html