java 整数计数器 - 最大值时该怎么办?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2017267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Integer counter - What to do when Max-Value?
提问by Andreas Hornig
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.
我的问题是关于java的。
回答by rayd09
You can tell whether you have hit the max value by comparing against Integer.MAX_VALUE.
您可以通过与 Integer.MAX_VALUE 进行比较来判断您是否达到了最大值。
回答by Tom Hawtin - tackline
For a fast saturated intincrement (one that stops when it gets to MAX_VALUE), I guess you could write:
对于快速饱和int增量(一个在达到 时停止MAX_VALUE),我想你可以写:
counters = (counter+1) + ((counter+1)>>31);
Or
或者
counters = (counter+1) - ((counter+1)>>>31);
Or in the interests of fun, for AtomicInteger, I think:
或者为了好玩,对于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));
}
回答by Dan Dyer
Choose a numeric type that has a range that is comfortably large enough for your requirements. So if intisn't big enough use longor BigInteger.
选择一个范围足够大的数字类型以满足您的要求。因此,如果int不够大,请使用long或BigInteger.
You'll know when your inthas surpassed Integer.MAX_VALUEbecause it will overflow and become negative.
你会知道什么时候你的int超过了,Integer.MAX_VALUE因为它会溢出并变成负数。
回答by Drew Wills
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)
- Integer.MAX_VALUE 是 2147483647
- Long.MAX_VALUE 是 9223372036854775807L(相当大)
If neither of those 2 is large enough, BigInteger has no maximum (except what your machine can handle).
如果这 2 个都不够大,则 BigInteger 没有最大值(除了您的机器可以处理的内容)。
In practice most things you want to count easily fit within an int.
在实践中,您想要轻松计算的大多数事情都适合在 int 中。
回答by Rodrick Chapman
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.
丹的回答是正确的。但是,如果您每次肯定递增 1 并且出于某种原因需要使用 int(无法想象为什么),那么您确实需要第二个计数器,例如 b,每次 a++ == max_value 都会递增(或 a++ % max_value == 0)。您可以对 b 等执行相同的操作。本质上,您只是在使用基数 max_value 算术而不是基数 10。
回答by Michael Madsen
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!)
如果您将其用作通过网络发送的请求消息的一种 ID 生成器,那么根据您的需要,您可能不关心溢出,因为到那时最旧的 ID 将已过期。如果以前从未见过该值很重要,那么您可以使用更大的数据类型——64 位长,您有超过 9 个 quintillion 值,所以应该足够了(尽管在许多情况下,21 亿个int 也应该足够了!)
回答by sepp2k
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).
用一个 int 作为计数器,用另一个 int 来计算溢出给你与 long 相同的范围(更少,实际上因为 int 是有符号的,这是溢出计数器浪费的一个位)。
You may want to use BigIntegers if you expect the counter to overflow.
如果您希望计数器溢出,您可能需要使用 BigIntegers。
回答by Jim
Java does not detect nor does it cause anything to occur with integer overflow, either negative or positive, with int or long types.
Java 不会检测也不会导致任何整数溢出,无论是负数还是正数,对于 int 或 long 类型。
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.
原始类型 int 和 long 以及它们对应的类类型 Int 和 Long 根据二进制补码算法在正或负方向上溢出。最大正值之后的第一个值是最大负值。对于整数,它是 Integer.MIN_VALUE。对于多头,它是 Long.MIN_VALUE。负溢出发生相反的情况。最大负值之后的第一个值是最大正值。对于整数,它是 Integer.MAX_VALUE。对于多头,它是 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.
使用递增 +1 的计数器,检测溢出的一种非常简单的方法是检查它是否已达到 int 的 Integer.MAX_VALUE 或 Long.MAX_VALUE 的 long 并采取一些优雅的动作,例如从 0 重新开始。替代方法是停止处理或适应二进制补码算法的行为,该行为会滚动到最大负值并从那里继续。如果溢出确实是一个问题,因为您使用的是非常大的整数,那么使用 BigInteger 类的实例。它几乎与 int 一样有效,并且可能比在您自己的代码中处理二进制补码翻转更有效。
回答by n0rm1e
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.
一旦溢出,它就会停止递增。
回答by fastcodejava
You can start counterfrom Integer.MAX_VALUEand go down. You can stop at Zeroor go upto -Integer.MAX_VALUE.
你可以开始counter从Integer.MAX_VALUE和往下走。您可以停在Zero或上升到-Integer.MAX_VALUE。

