java输出两个整数的积_如何检查Java中的两个数字相乘是否会导致溢出?
如何检查Java中的两个数字相乘是否会导致溢出?
我想处理两个数字相乘导致溢出的特殊情况。 代码看起来像这样:
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个解决方案
78 votes
对于int和long,Java 8有Math.multiplyExact,Math.addExact等。 这些在溢出时抛出未经检查的ArithmeticException。
bcoughlan answered 2019-08-26T05:16:03Z
59 votes
如果a和b都是正数,那么您可以使用:
if (a != 0 && b > Long.MAX_VALUE / a) {
// Overflow
}
如果你需要处理正数和负数,那么它就更复杂了:
long maximum = Long.signum(a) == Long.signum(b) ? Long.MAX_VALUE : Long.MIN_VALUE;
if (a != 0 && (b > 0 && b > maximum / a ||
b < 0 && b < maximum / a))
{
// Overflow
}
这是一个小桌子我掀起来检查这个,假装溢出发生在-10或+10:
a = 5 b = 2 2 > 10 / 5
a = 2 b = 5 5 > 10 / 2
a = -5 b = 2 2 > -10 / -5
a = -2 b = 5 5 > -10 / -2
a = 5 b = -2 -2 < -10 / 5
a = 2 b = -5 -5 < -10 / 2
a = -5 b = -2 -2 < 10 / -5
a = -2 b = -5 -5 < 10 / -2
John Kugelman answered 2019-08-26T05:16:43Z
17 votes
有些Java库提供安全的算术运算,可检查长溢出/下溢。 例如,Guava的LongMath.checkedMultiply(long a,long b)返回a和b的乘积,前提是它不溢出,如果a * b在带符号的long算术中溢出,则抛出ArithmeticException。
reprogrammer answered 2019-08-26T05:17:12Z
6 votes
您可以使用java.math.BigInteger来检查结果的大小(避免测试代码):
BigInteger bigC = BigInteger.valueOf(a) * multiply(BigInteger.valueOf(b));
if(bigC.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
c = Long.MAX_VALUE;
} else {
c = bigC.longValue()
}
Ulf Lindback answered 2019-08-26T05:17:39Z
6 votes
使用对数检查结果的大小。
High Performance Mark answered 2019-08-26T05:18:06Z
4 votes
Java有类似int.MaxValue的东西吗? 如果是,那就试试吧
if (b != 0 && Math.abs(a) > Math.abs(Long.MAX_VALUE / b))
{
// it will overflow
}
编辑:看到有问题的Long.MAX_VALUE
nothrow answered 2019-08-26T05:18:40Z
3 votes
从jruby偷来的
long result = a * b;
if (a != 0 && result / a != b) {
// overflow
}
更新:此代码简短,运行良好; 但是,它失败了a = -1,b = Long.MIN_VALUE。
一个可能的增强:
long result = a * b;
if( (Math.signum(a) * Math.signum(b) != Math.signum(result)) ||
(a != 0L && result / a != b)) {
// overflow
}
请注意,这将捕获一些溢出而不进行任何除法。
rogerdpack answered 2019-08-26T05:19:28Z
2 votes
我不确定为什么没有人在寻找解决方案:
if (Long.MAX_VALUE/a > b) {
// overflows
}
选择一个更大的两个数字。
fastcodejava answered 2019-08-26T05:20:01Z
2 votes
我希望以John Kugelman的答案为基础,而不是通过直接编辑来替换它。 它适用于他的测试用例(MIN_VALUE,MAX_VALUE),因为Long的对称性,这不是两个补码整数的情况。 实际上,Integer。
scala> (java.lang.Integer.MIN_VALUE, java.lang.Integer.MAX_VALUE)
res0: (Int, Int) = (-2147483648,2147483647)
scala> (java.lang.Long.MIN_VALUE, java.lang.Long.MAX_VALUE)
res1: (Long, Long) = (-9223372036854775808,9223372036854775807)
当应用于真实的MIN_VALUE和MAX_VALUE时,John Kugelman的答案会在Long和Integer的任何其他情况下产生溢出情况(由Kyle首先提出)。 以下是解决问题的方法:
long maximum = Long.signum(a) == Long.signum(b) ? Long.MAX_VALUE : Long.MIN_VALUE;
if ((a == -1 && b == Long.MIN_VALUE) ||
(a != -1 && a != 0 && ((b > 0 && b > maximum / a) ||
(b < 0 && b < maximum / a))))
{
// Overflow
}
它不是任何MIN_VALUE和MAX_VALUE的通用解决方案,但它通用于Java的Long和Integer以及任何值a和b。
Jim Pivarski answered 2019-08-26T05:20:47Z
2 votes
这是我能想到的最简单的方法
int a = 20;
long b = 30;
long c = a * b;
if(c / b == a) {
// Everything fine.....no overflow
} else {
// Overflow case, because in case of overflow "c/b" can't equal "a"
}
Naren answered 2019-08-26T05:21:16Z
1 votes
也许:
if(b!= 0 && a * b / b != a) //overflow
不确定这个&#34;解决方案&#34;。
编辑:添加b!= 0。
在你投票之前:a * b / b不会被优化。 这将是编译器错误。 我仍然没有看到可以掩盖溢出错误的情况。
Thomas Jung answered 2019-08-26T05:22:01Z
1 votes
也许这会对你有所帮助:
/**
* @throws ArithmeticException on integer overflow
*/
static long multiply(long a, long b) {
double c = (double) a * b;
long d = a * b;
if ((long) c != d) {
throw new ArithmeticException("int overflow");
} else {
return d;
}
}
dfa answered 2019-08-26T05:22:31Z
1 votes
正如已经指出的那样,Java 8具有Math.xxxExact方法,可以在溢出时抛出异常。
如果您没有将Java 8用于您的项目,您仍然可以&#34;借用&#34; 他们的实现非常紧凑。
以下是第三方网站上这些实现的一些链接,不保证这些实现是否保持有效,但无论如何您应该能够进入JDK源并看看他们如何在Math.addExact类中实现他们的魔力。
Math.addExact[http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Math.java?av=f#882]
Math.addExact[http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Math.java?av=f#805]
等等
StFS answered 2019-08-26T05:23:38Z
-1 votes
c / c ++(long * long):
const int64_ w = (int64_) a * (int64_) b;
if ((long) (w >> sizeof(long) * 8) != (long) w >> (sizeof(long) * 8 - 1))
// overflow
java(int * int,抱歉我在java中找不到int64):
const long w = (long) a * (long) b;
int bits = 32; // int is 32bits in java
if ( (int) (w >> bits) != (int) (w >> (bits - 1))) {
// overflow
}
1.将结果保存为大型(int * int将结果放入long,long * long放入int64)
2.cmp结果&gt;&gt; 位和结果&gt;&gt; (位 - 1)
xuan answered 2019-08-26T05:24:32Z
java输出两个整数的积_如何检查Java中的两个数字相乘是否会导致溢出?相关推荐
- 辗转相除法 定义函数fun求两个整数的最大公约数,主函数中输入两个整数,调用该函数得到最大公约数,最后在主函数中输出两个整数的最大公约数和最小公倍数。
定义函数fun求两个整数的最大公约数,主函数中输入两个整数,调用该函数得到最大公约数,最后在主函数中输出两个整数的最大公约数和最小公倍数. 参考运行截图: 欧几里得算法又称辗转相除法,是指用于计算两个 ...
- Java show两个整数加减_怎么样用java编写界面实现两个数的加法运算
展开全部 import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; ...
- python两个时间内的工作日_如何在Python中找到两个日期之间的星期一或任何其他工作日的数目?...
这是高效的-即使在开始和结束之间有一万天的时间-而且仍然非常灵活(它在sum函数内最多迭代7次):def intervening_weekdays(start, end, inclusive=True ...
- c语言,在主函数中输入一个整数,求该整数各位数字的乘积,[求助]求由键盘输入的任意两个整数的积...
[求助]求由键盘输入的任意两个整数的积 [问题已解决] 我是才接触C的新手,一共才上了4节课,老师就出题了,请高手帮忙看看(如果愿意帮忙改的,请尽量不要改变原来的变量):--------------- ...
- 给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
记录自己坑了又坑的每一天: 原题: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 div ...
- 给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符.返回被除数 dividend 除以除数 divisor 得到的商.示例 1:输入: ...
- 给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。
给你两个整数,被除数 dividend 和除数 divisor.将两数相除,要求 不使用 乘法.除法和取余运算. 整数除法应该向零截断,也就是截去(truncate)其小数部分.例如,8.345 将被 ...
- 程序员面试金典——解题总结: 9.18高难度题 18.5有个内含单词的超大文本文件,给定任意两个单词,找出在这个文件中这两个单词的最短距离
#include <iostream> #include <stdio.h> #include <vector> #include <string> # ...
- java整数的因式分解_如何在Java中找到整数的质数-因式分解
java整数的因式分解 编程课程中的常见家庭作业/任务之一是关于Prime Factorization. 要求您编写一个程序以找到给定整数的素因子 . 一个数字的素数因子是将精确地除以给定数字的所有素 ...
最新文章
- Android之 AndroidManifest xml 文件解析
- error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MTd_StaticDebug”不匹配值“MDd_DynamicDebug...
- (有图片)汇编工具dosbox下自动mount及切换虚拟目录使用步骤。
- 模拟撞击_模玩资讯:EPOCH 汽车撞击测试用模拟假人与实验车辆
- GraphQL在SAP Kyma中的广泛应用
- ImportError: cannot import name ‘constants‘
- 【渝粤教育】 国家开放大学2020年春季 2772家畜环境卫生与设施 参考试题
- 《MySQL——38道查询练习(无连接查询)》
- angular8多选框实现点击整行任意位置<tr>就可以选中多选框
- 多线程的那点儿事(之读写锁)
- html滚动选择框代码,如何使用最简单纯Css代码美化checkbox复选框、radios单选框和滑动按钮...
- 华为交换机配置syslog发送_配置华为交换机把日志发送到远程centos syslog服务器上...
- Linux : 文件处理命令
- python中的urllib模块中的方法
- 在vue2.0下安装axios
- SQL查询语句大全(个人总结)
- 测判三极管的口诀 (挑战者)
- Vue项目上线后刷新报错404问题(apache,nginx,tomcat)
- 【CPU GPU TPU】机器学习扫盲篇
- 树莓派之树莓派系统安装
热门文章
- oracle-01122,oracle ORA-01200ORA-01110ORA-01122
- 占用率_有问有答:任务管理器里面的GPU占用率到底是怎么算的?
- 程序员必备技能之单元测试
- php 批量修改表格数据,PHP批量修改数据库表前缀教程+代码
- oracle数据库十六进制转字符串,Oracle中各种进制相互转换
- python中matplotlib出错_Python中使用matplotlib的报错问题
- 【3】测试用例设计-因果图
- java判断栈中元素数目_Java数据结构与算法-栈和队列
- 无所不能java人_无所不能的java
- Lesson 3.1 - Python Core Data Types