我想处理两个数字相乘导致溢出的特殊情况。代码如下所示:
int a = 20;
long b = 30;
// if a or b are big enough, this result will silently overflow
long c = a * b;
这是一个简化的版本。在真实的程序中 a
以及 b
在运行时从其他地方获取。我想要达到的目标是:
long c;
if (a * b will overflow) {
c = Long.MAX_VALUE;
} else {
c = a * b;
}
你觉得我最好怎么写这个?
更新: a
以及 b
在我的场景中总是非负的。
14条答案
按热度按时间uyhoqukh1#
这是我能想到的最简单的方法
watbbzwu2#
正如已经指出的,Java8有math.exact方法,这些方法在溢出时抛出异常。
如果您的项目没有使用Java8,您仍然可以“借用”它们的实现,它们非常紧凑。
下面是jdk源代码存储库中这些实现的一些链接,不能保证这些实现是否有效,但无论如何,您应该能够下载jdk源代码,并查看它们如何在存储库中发挥作用
java.lang.Math
班级。Math.multiplyExact(long, long)
http://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/java/lang/math.java#l925Math.addExact(long, long)
http://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/java/lang/math.java#l830等等,等等。
更新:切换到第三方网站的无效链接到openjdk的mercurial存储库的链接。
iq0todco3#
我想建立在约翰库格曼的答案,而不是取代它直接编辑。它适用于他的测试用例(
MIN_VALUE = -10
,MAX_VALUE = 10
)因为MIN_VALUE == -MAX_VALUE
,这不是2的补码整数的情况。实际上,MIN_VALUE == -MAX_VALUE - 1
.当应用于真
MIN_VALUE
以及MAX_VALUE
,john kugelman的回答产生了一个溢出情况a == -1
以及b ==
其他的(凯尔首先提出的观点)。下面是一个解决方法:这不是解决任何问题的一般办法
MIN_VALUE
以及MAX_VALUE
,但对于java的Long
以及Integer
有什么价值吗a
以及b
.4urapxun4#
Java8有
Math.multiplyExact
,Math.addExact
对于int和long等。这些都是不受约束的ArithmeticException
溢出时。42fyovps5#
也许这会帮助你:
2exbekwf6#
java库提供了安全的算术运算,用于检查长溢出/下溢。例如,guava的longmath.checkedmultiply(long a,long b)返回
a
以及b
,前提是它不溢出,并抛出ArithmeticException
如果a * b
签名中溢出long
算术。fquxozlt7#
我不知道为什么没有人会考虑这样的解决方案:
从两个数字中选择一个较大的。
f4t66c6m8#
您可以改用java.math.biginteger并检查结果的大小(尚未测试代码):
j1dl9f469#
java有类似int.maxvalue的东西吗?如果是,那么试试
编辑:看到有问题的long.max\u值
1mrurvl110#
也许 吧:
不确定这个“解决方案”。
编辑:添加了b!=0
在你否决之前:a*b/b不会被优化。这可能是编译器错误。我仍然没有看到可以掩盖溢出错误的情况。
ghhaqwfi11#
如果
a
以及b
两者都是正值,则可以使用:如果你需要同时处理正数和负数,那就更复杂了:
这里有一张小table,我用它来检查,假装溢出发生在-10或+10:
bogh5gae12#
c/c++(长*长):
java(int*int,对不起,我没有在java中找到int64):
1.以大字体保存结果(intint将结果放入long,longlong放入int64)
2.cmp结果>>位和结果>>(位-1)
bksxznpy13#
使用对数检查结果的大小。
5gfr0r5j14#
从jruby偷来的
更新:这个代码很短,效果很好;但是,对于a=-1,b=long.min\u值,它将失败。
一个可能的增强:
注意,这将捕获一些没有任何除法的溢出。