整数计数器 - Max-Value时该怎么办?

时间:2010-01-07 00:04:05

标签: java

使用整数计数器时,如何解决最大值问题,看起来像

counter = counter + 1;

当达到最大值时,你怎么知道这发生了?你是否计算了另一个计数器来计算这种情况发生的频率?

我的问题是关于java。

10 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

选择一个数字类型,其范围足够大,可满足您的要求。因此,如果int不够大,请使用longBigInteger

您会知道int何时超过Integer.MAX_VALUE,因为它会溢出并变为负数。

答案 2 :(得分:4)

对于快速饱和的int增量(当它到达MAX_VALUE时会停止),我想你可以这样写:

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

或者

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

或者为了有趣,对于AtomicInteger,我认为:

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

答案 3 :(得分:3)

你必须知道“计数器”变量有多大可能增长。

  • Integer.MAX_VALUE是2147483647
  • Long.MAX_VALUE是9223372036854775807L(相当大)

如果这两个都不够大,BigInteger没有最大值(除了你的机器可以处理的内容)。

在实践中,您想要计算的大多数事物都很容易适合int。

答案 4 :(得分:2)

丹的回答是正确的。但是,如果你肯定每次增加1并且由于某种原因你需要使用int(无法想象为什么)那么你确实需要第二个计数器,比如b,每次++ == max_value时都会增加(或+ %% max_value == 0)。你也可以为b做同样的事情。基本上你只是在基数max_value算术而不是基数10。

答案 5 :(得分:1)

嗯,你做什么取决于你需要它。

如果您将其作为一种ID生成器用于通过网络发送请求消息,那么,根据您的需要,您可能不关心溢出,因为最早的ID将在此时过期。如果以前从未见过这个值很重要,那么你使用一个更大的数据类型 - 64位长,你有超过9个quintillion值,所以这应该是充足的(尽管在许多情况下,21亿int也应该足够了!)

答案 6 :(得分:1)

将一个int作为计数器,另一个int来计算溢出,给出与long相同的范围(更少,实际上是int符号,这是溢出计数器的一个浪费位)。

如果您希望计数器溢出,可能需要使用BigIntegers。

答案 7 :(得分:1)

Java不会检测也不会导致整数溢出发生任何事情,无论是负数还是正数,使用int或long类型。

基本类型int和long,以及它们对应的类类型Int和Long,根据二进制补码算法在正方向或负方向上溢出。最大正值之后的第一个值是最大负值。对于int,它是Integer.MIN_VALUE。对于多头,它是Long.MIN_VALUE。负溢出发生相反的情况。最大负值之后的第一个值是最大正值。对于int,它是Integer.MAX_VALUE。对于多头,它是Long.MAX_VALUE。

使用递增+1的计数器,检测溢出的一种非常简单的方法是检查它是否已经为int或Long.MAX_VALUE达到Integer.MAX_VALUE一段时间并采取一些优雅的操作,例如重新开始从0开始。另一种方法是停止处理或容纳二进制补码算法的行为,该算法将翻转到最大负值并从那里继续。如果溢出确实是一个问题,因为您使用的是非常大的整数,那么请使用BigInteger类的实例。它几乎与int一样高效,并且可能比在您自己的代码中处理二进制补码更有效。

答案 8 :(得分:0)

回答这个问题可能有点迟,但我倾向于这样做。

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

一旦溢出就停止递增。

答案 9 :(得分:-2)

您可以从counter开始Integer.MAX_VALUE然后向下。您可以停在Zero或最后-Integer.MAX_VALUE