views:

426

answers:

8

How do you solve the max value problem when using an integer counter, that looks like

counter = counter + 1;

When this reaches the max value, how do you know this happened? Do you add another counter for this counting how often this happened?

My question concerns about java.

+3  A: 

Choose a numeric type that has a range that is comfortably large enough for your requirements. So if int isn't big enough use long or BigInteger.

You'll know when your int has surpassed Integer.MAX_VALUE because it will overflow and become negative.

Dan Dyer
+1  A: 

Well, what you do depends on what you need it for.

If you're doing it as a sort of ID generator for request messages being sent over a network, then, depending on your needs, you might not care about the overflow, because the oldest IDs will have expired by then. If it's important that the value has never been seen before, then you use a larger datatype - with a 64-bit long, you have more than 9 quintillion values, so that should be plenty (although in many cases, the 2.1 billion of an int should be enough too!)

Michael Madsen
Just to put things into perspective: If you exhausted all ~4.3 billion values for an unsigned 32-bit integer in one second, it would take you approximately 68 years to exhaust a long, assuming constant speed - that's about 2 IDs per 3 people on Earth *every second*, which is insanely unrealistic.
Michael Madsen
By the time the long rolls over, you will not need to care about it, because either the ID will have expired and can be reused, or you have the far bigger problem of being able to store many exabytes - if not zettabytes or even yottabytes - of data (someone's using the ID for something, so there must be some data associated with it).
Michael Madsen
+1  A: 

Having one int as a counter and another int to count the overflows gives you the same range as a long (less, actually as ints are signed, which is one wasted bit for the overflow counter).

You may want to use BigIntegers if you expect the counter to overflow.

sepp2k
+3  A: 

You can tell whether you have hit the max value by comparing against Integer.MAX_VALUE.

rayd09
Sometime "simple is the best" :)
Adrian
+2  A: 

Dan's answer is correct. However, if you're definitely incrementing by 1 each time and you need to use an int for some reason (can't imagine why) then you would indeed need a second counter, say b, that get's incremented every time a++ == max_value (or a++ % max_value == 0). You can do the same for b and so on. Essentially you're just working in base max_value arithmetic instead of base 10.

Rodrick Chapman
Nice idea - though it's going to be fun trying to actually combine all of those counters together at the end: `int total = c * Integer.MAX_VALUE * Integer.MAX_VALUE + b * Integer.MAX_VALUE + a`... ;-)
Andrzej Doyle
+2  A: 

You have to know something about how large the 'counter' variable is likely to grow.

  • Integer.MAX_VALUE is 2147483647
  • Long.MAX_VALUE is 9223372036854775807L (considerably larger)

If neither of those 2 is large enough, BigInteger has no maximum (except what your machine can handle).

In practice most things you want to count easily fit within an int.

Drew Wills
A: 

You can start counter from Integer.MAX_VALUE and go down. You can stop at Zero or go upto -Integer.MAX_VALUE.

fastcodejava
This doesn't solve the problem of detecting or coping with overflow, though. Counting from MAX_VALUE down to zero will be exhausted after the same number of ticks as counting from zero up to MAX_VALUE anyway. Plus the counter value would be *much* harder to work with (I can guarantee someone will forget that the "real" value is `MAX_VALUE - counter` in any non-trivial situation).
Andrzej Doyle
+1  A: 

For a fast saturated int increment (one that stops when it gets to MAX_VALUE), I guess you could write:

counters = (counter+1) + ((counter+1)>>31);

Or

counters = (counter+1) - ((counter+1)>>>31);

Or in the interests of fun, for AtomicInteger, I think:

private final AtomicInteger counter = new AtomicInteger(0);

public void increment() {
    int count;
    do {
        count = counter.get();
        if (count == Integer.MAX_VALUE) {
            return;
        }
    } while (!counter.compareAndSet(count, count+1));
}
Tom Hawtin - tackline