How does java handle integer overflow and underflow? - java

i know this is an old question, asked many times. but i am not able to find any satisfactory answer for this, hence asking again.
can someone explain what exactly happens in case of integer overflow and underflow?
i have heard about some 'lower order bytes' which handle this, can someone explain what is that?
thanks!

You could imagine that when you have only 2 places you are counting (so adding 1 each time)
00
01
10
11
100
But the last one gets cut down to "00" again. So there is your "overflow". You're back at 00. Now depending on what the bits mean, this can mean several things, but most of the time this means you are going from the highest value to the lowest. (11 to 00)
Mark peters adds a good one in the comments: even without overflow you'll have a problem, because the first bit is used as signing, so you'll go from high to low without losing that bit. You could say that the bit is 'separate' from the others

Java loops the number either to the maximum or minimum integer (depending on whether it is overflow or underflow).
So:
System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE);
System.out.println(Integer.MIN_VALUE - 1 == Integer.MAX_VALUE);
prints true twice.

It basically handles them without reporting an exception, performing the 2's complement arithmetic without concern for overflow or underflow, returning the expected (but incorrect) result based on the mechanics of 2's complement arithmetic.
This means that the bits which over or underflow are simply chopped, and that Integer.MIN_VALUE - 1 typically returns Integer.MAX_VALUE.
As far as "lower order bytes" being a workaround, they really aren't. What is happening when you use Java bytes to do the arithmetic is that they get expanded into ints, the arithmetic is generally performed on the ints, and the end result is likely to be completely contained in the returned it as it has far more storage capacity than the starting bytes.

Another way to think of how java handles overflow/underclock is to picture an anology clock. You can move it forward an hour at a time but eventually the hours will start again. You can wind the clock backward but once you go beyond the start you are at the end again.

Related

Double as close to 0 as possible?

I need a value as close to 0 as possible. I need to be able to divide through this value, but it should be effectively 0.
Does Java provide an easy way of generating a double with only the least significant bit set? Or do I have to calculate it myself?
//EDIT: A little background information, because someone requested it. I know that my soultion is not a particularly clean one, but here you are:
I am writing a program for homework. It calculates the resistance of a circuit consisting of multiple resistors in parallel and serial circuits.
It is a 2nd year programming class. Our teacher still designs classes for us, we need to implement them according to his design.
Parallel circuits involve calculation of 1/*resistance*, therefore my program prohibits creation of resistors with 0 Ohm. Physics tells you that this is impossible anyway (you have just a tiny little resistance in every metal).
However, the example circuit we should use to test the program contains a 0 Ohm resistor. It is placed in a serial circuit, but resistors do not know where they are (the teacher designed it that way), so I cannot change my program to allow resistors with 0 Ohm resistance in serial circuits only.
Two solutions:
Allow 0 Ohm resistors in any case - if division by 0 occurs, well, bad luck
Set the resistor not to 0, but to a resistance one can neglect.
Both are not very good. The first one seemed not too good to me, and neither did the second, but I had to decide.
It was just a random choice that threw up the problem. I could not let go without solving it, so switching to the first one was not an option anymore ;-)
Use Double.MIN_VALUE:
A constant holding the smallest positive nonzero value of type double, 2-1074. It is equal to the hexadecimal floating-point literal 0x0.0000000000001P-1022 and also equal to Double.longBitsToDouble(0x1L).
If you would like to divide by "zero" you can actually just use Double.POSITIVE_INFINITY as the result.

Is it more efficient to reset a counter or let it increase and use modulo

Say you need to track the number of times a method is called and print something when it has been called n times. What would be the most efficient:
Use a long variable _counter and increase it each time the method is called. Each call you test for the equality "_counter % n == 0"
Use an int variable _counter and increase it each time the method is called. When _counter = n, print the message and reset the variable _counter to 0.
Some would say the difference is negligible and you are probably right. I am just curious of what method is most commonly used
In this particular case, since you need to have an if-statement ANYWAY, I would say that you should just set it to zero when it reaches the count.
However, for a case where you use the value every time, and just want to "wrap round to zero when we reach a certain value", then the case is less obvious.
If you can adjust n to be a power of 2 (2, 4, 8, 16, 32 ...), then you can use the trick of counter % n is the same as counter & (n-1) - which makes the operation REALLY quick.
If n is not a power of two, then chances are that you end up doing a real divide, which is a bad idea - divide is very expensive, compared to regular instructions, and a compare and reset is highly likely faster than the divide option.
Of course, as others have mentioned, if your counter ever reaches the MAX limit for the type, you could end up with all manner of fun and games.
Edit: And of course, if you are printing something, that probably takes 100 times longer than the divide, so it really is micro-optimization, unless n is quite large.
It depends on the value of n... but I bet resetting and a simple equality check is faster.
Additionally resetting the counter is safer, you will never reach the representation limit for your number.
Edit: also consider readability, doing micro optimizations may obscure your code.
Why not do both.
If it becomes a problem then look to see if it is worth optimizing.
But there is no point even looking at it until it is a problem (there will be much bigger problems in your algorithms).
count = (count+1) % countMax;
I believe that it is always better to reset the counter for the following reasons:
The code is clearer to an unfamiliar programmer (for example, the maintenance programmer).
There is less chance of an arithmetic (perhaps bad spelling) overflow when you reset the counter.
Inspection of Guava's RateLimiter will give you some idea of a similar utility implementation http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html
Here are performance times for 100000000 iterations, in ms
modTime = 1258
counterTime = 449
po2Time = 108
As we see Power of 2 outperforms other methods by far, but its only for powers of 2, also our plain counter is almost 2.5 times faster than modulus as well. So why would we like to use modulus increments at all? Well in my opinion I think they provide a clean code and if used properly they are a great tool to know of
original post

How to get the last digits of 2 power

I’m working on a problem where its demanded to get the last 100 digits of 2^1001. The solution must be in java and without using BigInteger, only with int or Long. For the moment I think to create a class that handle 100 digits. So my question is, if there is another way the handle the overflow using int or long to get a number with 100 digits.
Thanks for all.
EDITED: I was off by a couple powers of 10 in my modulo operator (oops)
The last 100 digits of 2^1001 is the number 2^1001 (mod 10^100).
Note that 2^1001 (mod 10^100) = 2*(2^1000(mod 10^100)) (mod 10^100).
Look into properties of modulo: http://www.math.okstate.edu/~wrightd/crypt/lecnotes/node17.html
This is 99% math problem, 1% programming problem. :)
With this approach, though, you wouldn't be able to use just an integer, as 10^100 won't fit in an int or long.
However, you could use this to find, say, the last 10 digits of 2^1001, then use a separate routine to find the next 10 digits, etc, where each routine uses this feature...
The fastest way to do it (coding wise) is to create an array of 100 integers and then have a function which starts from the ones place and doubles every digit. Make sure to take the modulus of 10 and carry over 1s if needed. For the 100th digit, simply eliminate the carry over. Do it 1001 times and you're done.

Normalized Iteration Count does not work. What am I doing wrong?

As you can see from the title, I'm busy programming a little programm for visualizing fractals in Java. Anybody who deals with fractals will come to the point where he/she searches for a solution to get these stupid "bands" away, when you just colour a pixel by the number of iterations it took to escape.
So I searched for a more advanced colouring algorithm, finding the "normalized iteration count". The formula I'm using is:
float loc = (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);
Everybody on the Internet is so happy about this algorithm, everybody uses it, everbody gets great results. Except me. I thought, this algorithm should provide a float between 0 and 1. But that doesn't happen. I did some calculations and came to the conclusion, that this algorithm only works for c.abs() >= Math.E && c.abs() <= Math.exp(2) (that is Math.E * Math.E).
In numbers this means, my input into this equation has to be between about 2.718 and 7.389.
But a complex number c is considerd to tend towards infinity when its magnitude gets greater than 2. But for any Input smaller than Math.E, I get a value greater than one. And for any number greater than Math.exp(2), it gets negative. That is the case if a complex number escapes really fast.
So please tell me: what am I doing wrong. I'm desperate.
Thanks.
EDIT:
I was wrong: the code I posted is correct, I just
1. used it the wrong way and so it didn't provide the right output.
2. had to set the bailout value of the mandelbrot/julia algorithm to 10, otherwise I would've got stupid bands again.
Problem solved!
As you've already discovered, you need to increase the bailout radius before smoothing will look right.
Two is the minimum length that a coordinate can have such that when you square it and add the initial value, it cannot result in a smaller length. If the previous length was 2.0, and you squared it, you'd have a length of 4.0 (pointing in whichever direction), and the most that any value of c could reduce that by is 2.0 (by pointing in precisely the opposite direction). If c were larger than that then it would start to escape right away.
Now, to estimate the fractional part of the number of iterations we look at the final |z|. If z had simply been squared and c not added to it, then it would have a length between 2.0 and 4.0 (the new value must be larger than 2.0 to bail out, and the old value must have been less than 2.0 to have not bailed out earlier).
Without c, taking |z|'s proportional position between 2 and 4 gives us a fractional part of the number of iterations. If |z| is close to 4 then the previous length must have been close to 2, so it was already close to bailing out in the previous iteration and the smoothed result should be close to the previous iteration count to represent that. If it's close to 2, then the previous iteration was further from bailing out, and so the smoothed result should be closer to the new iteration count.
Unfortunately c messes that up. The larger c is, the larger the potential error is in that simple relationship. Even if the old length was nearly at 2.0, it might have landed such that c's influence made it look like it must have been smaller.
Increasing the bailout mitigates the effect of adding c. If the bailout is 64 then the resulting length will be between 64 and 4096, and c's maximum offset of 2 has a proportionally smaller very impact on the result.
You have left out the iteration value, try this:
float loc = <iteration_value> + (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);
The iteration_value is the number of iterations which yielded c in the formula.

How can I simulate erroneous bit transmission through a wire?

So I have the following homework, but I don't understand exactly what the process is. Has anyone seen this question before or actually understands what the logic should be? I don't want code, I know how to program, but I don't exactly know what to do here.
Consider a wire across which data is transmitted bit-by-bit. Occasionally, a bit or a group of
consecutive bits is transmitted incorrectly. If the previous bit was transmitted correctly, the
probability that the current bit is transmitted incorrectly is 0.1. If the previous bit was
transmitted incorrectly, the probability that the current bit is also transmitted incorrectly
is 0.3. Write a program called BitError.java that simulates the transmission of one million
bits and prints out the percentage of bits transmitted incorrectly.
(Hint: According to theory, the expected answer is 12.5%.)
You test for the probability of an event happening as follows
Generate a uniform random number between 0 and 1
If the number generated is less than the prob an event happening then the event happend
Your code should look something like this
// Generate random bit either a 0 or a 1
int bit = RandInt(0,1)
// Assume first bit was correct
bool bPreviousWasCorrect = false;
Loop 1 million times
double probBitIsCorrect = RandUnif(0,1) // get a random number between 0 and 1
if bPreviousWasWrong then
// if an error has occured then a 2nd error occurs with prob 0.3
if (probBitIsCorrect < 0.3) then
Set bPreviousWasWrong to true
increment number of wrong bits
else
Set bPreviousWasWrong to false
increment number of correct bits
end if
else
if (probBitIsCorrect < 0.1) then
Set bPreviousWasWrong to true
increment number of wrong bits
else
Set bPreviousWasWrong to false
increment number of correct bits
end if
Display results when done
They want you to write a simulator. You make a loop which does one million iterations, each iteration representing the transmission of one bit. Every time you decide randomly if the bit gets transmitted correctly or incorrectly, based on the two rules, and keep count.
At the end, your simulation will tell you how many bits were transmitted correctly (which should apparently be close to 87.5%).
ok, so you need to "transmit" the data bit by bit and on each iteration calculate the probability.
let's consider that the transmission of the first bit is with the probability of a bit with a preceding correct transmission. this means that the first bit's probability to be transmitted correctly is 0.9
next iteration:
if bit 1 was transmitted correctly, do probability 0.9 for correct, otherwise 0.7
That's why it's called homework.... It's deigned so that you don't exactly know what to do.
The problem relates to recursion and iteration. Google: Recursion. Given the current state (whether or not the previous bit was transmitted correctly or not) you can calculate the probability that the current bit is transmitted correctly. After that, it's simple probability (e.g. multiplication) to get 12.5%. You may even be able to do it without looping through all the bits, depending on how much statistics you know.
At the end you should know all about recursion. That's what the assignment is really about. What is your base case (i.e. the first bit) and what is your recursive step (i.e. each bit thereafter)? Once you understand that, writing the Java should be easy.

Categories