简体   繁体   中英

Integer counter - What to do when Max-Value?

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.

您可以通过与Integer.MAX_VALUE进行比较来判断是否达到了最大值。

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.

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));
}

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.

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.

Java does not detect nor does it cause anything to occur with integer overflow, either negative or positive, with int or long types.

The primitive types int and long, along with their corresponding class types, Int and Long, overflow in either positive or negative direction in accordance with two's complement arithmetic. The first value after the maximum positive value is the maximum negative value. For ints, it is Integer.MIN_VALUE. For longs, it is Long.MIN_VALUE. The reverse happens with negative overflow. The first value after the maximum negative value is the maximum positive value. For ints, it is Integer.MAX_VALUE. For longs, it is Long.MAX_VALUE.

With a counter that increments by +1, a very simple way to detect overflow is to check to see if it has reached Integer.MAX_VALUE for an int or Long.MAX_VALUE for a long and take some graceful action such as starting over from 0. The alternative is to halt processing or accomodate the behavior of two's complement arithmetic which is rolls over to the maximum negative value and proceeds from there. If overflow is really an issue because you are using really large integers, then use an instance of the BigInteger class. It is almost as efficient as an int and likely a lot more efficient than handling the two's complement roll-over in your own code.

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!)

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.

It might be a little late to answer this question, but I tend to do something like this.

    if (atomicInt.get() < 0 || atomicInt.incrementAndGet() > MAX) {
        // ...
    }

It stops incrementing once it overflows.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM