回答
对于一个快速饱和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));
}
选择一个数值类型,其范围足以满足您的要求。因此,如果int
不够大,请使用long
或BigInteger
。
当您的int
超过Integer.MAX_VALUE
时,您会知道它会溢出并变为负值。
那么,你做什么取决于你需要什么。
如果您是通过网络发送请求消息的一种ID生成器,那么根据您的需要,您可能不会在意溢出,因为最早的ID将在此时过期。如果以前从未见过该值是重要的,那么您使用的数据类型较大 - 一个64位长的数据类型,你有9个以上的值,所以应该是很多的(尽管在很多情况下,21亿美元诠释应该是足够了!)
只是将事情看得很透彻:如果你在一秒内耗尽了大约43亿个无符号32位整数的值,假定速度恒定需要大约68年的时间 - 这大约是每3人2个ID在地球*每秒*,这是疯狂的不切实际的。 – 2010-01-07 00:42:39
在长时间翻身时,您不需要关心它,因为ID可能已经过期并且可以重复使用,或者您有更大的问题能够存储许多EB字节数 - 如果不是Z字节或甚至yottabytes - 数据(某人使用ID作为事物,所以必须有一些与之相关的数据)。 – 2010-01-07 00:43:14
有一个int作为计数器和另一个int来计数溢出给你相同的范围作为长(实际上,因为整数签名,这是一个溢出计数器浪费位)。
如果您希望计数器溢出,您可能需要使用BigIntegers。
丹的答案是正确的。但是,如果你肯定每次递增1,并且出于某种原因需要使用int(无法想象为什么),那么你确实需要第二个计数器,比如说b,每次都增加一个++ == max_value (或++%max_value == 0)。你可以为b等做同样的事情。本质上,你只是在基础max_value算术,而不是基数为10.
不错的想法 - 虽然它会很有趣,试图将所有这些计数器结合在一起:int total = c * Integer.MAX_VALUE * Integer.MAX_VALUE + b * Integer .MAX_VALUE + a' ... ;-) – 2010-01-07 01:52:52
你必须知道'counter'变量可能增长的大小。
- Integer.MAX_VALUE的是2147483647
- Long.MAX_VALUE是9223372036854775807L(相当大)
如果没有这些2的足够大,BigInteger的没有最大(除非你的机器能处理) 。
在实践中,你想要计算的大部分东西很容易适合int。
您可以从Integer.MAX_VALUE
开始counter
并关闭。你可以停在Zero
或去-Integer.MAX_VALUE
。
但这并不能解决检测或应对溢出的问题。无论如何,从MAX_VALUE到MAX_VALUE的相同数量的滴答数量将从MAX_VALUE降到零。此外,计数器的值会很难处理(我可以保证在任何非平凡的情况下,有人会忘记“真实”值是“MAX_VALUE - counter”)。 – 2010-01-07 01:55:09
Java没有解决ct也不会导致整数溢出发生任何事情,无论是负值还是正值,使用int或long类型。
原始类型int和long及其对应的类类型Int和Long根据二进制补码算法在正方向或负方向溢出。最大正值之后的第一个值是最大负值。对于整数,它是Integer.MIN_VALUE。长期以来,它是Long.MIN_VALUE。反过来发生负溢出。最大负值之后的第一个值是最大正值。对于整数,它是Integer.MAX_VALUE。长期以来,它是Long.MAX_VALUE。
使用递增+1的计数器,检测溢出的一种非常简单的方法是检查它是否已达到Integer.MAX_VALUE(对于int或Long.MAX_VALUE很长时间),并采取一些优雅动作,如启动从0开始。另一种方法是停止处理或容纳二进制补码运算的行为,该运算将滚动到最大负值并从那里继续。如果溢出确实是一个问题,因为您使用的是非常大的整数,那么请使用BigInteger类的实例。它几乎和int一样有效,并且可能比在自己的代码中处理二进制补码翻转更有效率。
回答这个问题可能有点晚,但我倾向于做这样的事情。
if (atomicInt.get() < 0 || atomicInt.incrementAndGet() > MAX) {
// ...
}
一旦溢出就停止递增。
- 1. 当你需要mysql上大于20位数的整数时该怎么办?
- 2. 当数据变得太大以至于web.config时该怎么办
- 3. 我该怎么办?
- 4. 该怎么办? javascript数组练习
- 5. NullPointerException - 该怎么办?
- 6. array_push key =>值,该怎么办?
- 7. Symfony2手动部署时该怎么办?
- 8. rubygems.org关闭时该怎么办?
- 9. 当inptr == NULL时我该怎么办?
- 10. 从xml下载数据时浪费时间,我该怎么办?
- 11. 怎么办根据计数的更新 -
- 12. 怎么回事最大值
- 13. 如果_POSIX_VDISABLE值为-1,该怎么办?
- 14. 缺少基础SDK时该怎么办?
- 15. SQLite3整数最大值
- 16. 我该怎么办在PHP
- 17. RemotingConfiguration.Configure失败时该怎么办?
- 18. VBA excel计数器最大值
- 19. 指数值没有显示,我该怎么办?
- 20. GWT JDBC我该怎么办?
- 21. 我该怎么办用C
- 22. “ConnectionResetError”我该怎么办?
- 23. Heroku下降时该怎么办?
- 24. sys.stdout.encoding为None时该怎么办?
- 25. 卸载rubygems-update时该怎么办?
- 26. 最佳实践:视图控制器加载时间很长时该怎么办?
- 27. 当一个参数不起作用时该怎么办?
- 28. 验证数据的外部服务失败时该怎么办?
- 29. 当JavaScript中有不同的输入数组时,该怎么办?
- 30. NSUnknownKeyException查看...该怎么办?
嗨大卫, 我这样做,但有些仍然打开,用户想要稍后编辑或关闭。所以没有太多的问题要检查和回答。 :) – 2010-01-07 00:12:26
@Andreas:不用担心编辑部分 - 如果用户想编辑他们的答案,他们仍然可以在接受它之后做到这一点。 – 2010-01-07 01:51:10