使用整数计数器时,如何解决最大值问题,看起来像
counter = counter + 1;
当达到最大值时,你怎么知道这发生了?你是否计算了另一个计数器来计算这种情况发生的频率?
我的问题是关于java。
答案 0 :(得分:7)
您可以通过与Integer.MAX_VALUE进行比较来判断您是否达到了最大值。
答案 1 :(得分:4)
选择一个数字类型,其范围足够大,可满足您的要求。因此,如果int
不够大,请使用long
或BigInteger
。
您会知道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)
你必须知道“计数器”变量有多大可能增长。
如果这两个都不够大,BigInteger没有最大值(除了你的机器可以处理的内容)。
在实践中,您想要计算的大多数事物都很容易适合int。
答案 4 :(得分:2)
答案 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
。