我的问题与此有关 我如何检查Java中的两个数字相乘是否会导致溢出?
在我的应用程序中,x和y是动态计算的,在我的公式中的某处我必须乘以x和y.
     int x=64371;
     int y=64635;
     System.out.println((x*y));
我得错了输出 -134347711 
我可以通过更改变量x和y类型快速修复上面的内容int,long并获得上述案例的正确答案.但是,没有出示担保说x和y不会增长超过最大容量long为好.
题
为什么我在这里得到一个负数,即使我没有将最终结果存储在任何变量中?(为了好奇)
因为,我不会提前知道x和y的值,有没有更快的方法来避免这种溢出.也许通过将所有x和y除以某个大常数来整个应用程序运行,或者我应该log在乘以它们之前采用x和y?(实际问题)
编辑:
澄清
应用程序在大数据集上运行,这需要数小时才能完成.拥有一个不太慢的解决方案会更好.
由于最终结果用于比较(它们只需要与原始结果成比例),如果能够获得巨大的性能提升,则最终值中的误差为±5%是可以接受的.
如果您知道数字可能很大,请BigInteger改用.保证不会溢出,然后您可以检查结果是否太大而无法放入int或long,或者您可以直接使用该BigInteger值.
BigInteger是一个任意精度等级,所以它会比使用直接原始值(这大概可以存储在处理器寄存器)慢,所以弄清楚你是否正在切实将要溢出一个long(一个int倍int永远会适合a long),并选择BigInteger您的域名是否真的需要它.
1为负数的任何整数解释.BigInteger.但是,您的代码看起来会非常不同,因为Java缺少运算符重载功能,这会使BigInteger对象的数学运算看起来很熟悉.代码也会慢一些.但是,您将保证不会出现溢出和下溢.编辑:
如果能够获得巨大的性能提升,那么最终值的误差为±5%是可以接受的.
+ -5%的错误是一个巨大的错误补贴!如果您的系统确实可以接受,那么使用double甚至float可以使用.这些类型是不精确的,但它们的范围远大于a的范围int,并且它们不会如此容易地溢出.但是,您必须非常小心,因为浮点数据类型本质上是不精确的.您需要始终牢记数据的表示方式,以避免常见的精度问题.