JAVA8系列教程-Math类中的精确算术运算支持
Java 8为Java开发人员带来了许多很棒的功能。所有更改都与lambda表达式有关,lambda表达式是最受关注的获取者,也是某种意义上的改变游戏规则的人。
除了上述更改之外,我们还获得了非lambda表达式更改。我已经在上文中讨论过String.join()方法。在本文中,我将讨论Math类中为支持精确算术所做的更改。
这篇文章中的部分:
1)(加|减|乘|减|负)精确方法
2)floorMod和floorDiv方法
3)toIntExact方法
4)nextDown方法
让我们一一讨论。
1)(加|减|乘|减|负)精确方法
Math类提供了这些新方法,它们"java.lang.ArithmeticException"
每次在操作结果溢出到最大限制时都会引发异常。以上所有方法都将参数作为int或long原语。
例如,考虑乘以100000 *100000。通常,这样做会“无声地”给您带来错误的返回,并且在应用程序运行时,您有责任每次检查最大限制以避免错误的计算。
在Java 8中,multiPlyExact
方法将为您完成工作,并且如果结果超出最大限制,则将引发异常。
//Normal multiplication System.out.println( 100000 * 100000 ); //Using multiPlyExact System.out.println( Math.multiplyExact( 100000 , 100000 )); Output: 1410065408 //Incorrect result Exception in thread "main" java.lang.ArithmeticException: integer overflow at java.lang.Math.multiplyExact(Math.java: 867 ) at java8features.MathematicalFuctions.main(MathematicalFuctions.java: 8 ) |
其他操作也会发生相同的情况。例如添加操作与addExact
//Normal add operation System.out.println( Integer.MAX_VALUE + Integer.MAX_VALUE ); //Using addExact System.out.println( Math.addExact( Integer.MAX_VALUE , Integer.MAX_VALUE )); Output: - 2 //incorrect result Exception in thread "main" java.lang.ArithmeticException: integer overflow at java.lang.Math.addExact(Math.java: 790 ) at java8features.MathematicalFuctions.main(MathematicalFuctions.java: 11 ) |
2)floorMod和floorDiv方法
Java 8已经解决了很长的整数余数问题。每个人都知道表达n % 2
是
i) 0:如果数字是偶数
ii) 1:如果是奇数
如果数字为负怎么办。上面的表达式可以/不能返回-1。如果事实为负数,结果对我来说是不可预测的。
System.out.println( 10 % 2 ); System.out.println( 11 % 2 ); System.out.println( - 15 % 2 ); System.out.println( - 16 % 2 ); Output: 0 1 - 1 0 |
现在,使用Java 8附带的精确数学执行上述mod操作。
System.out.println( Math.floorMod( 10 , 2 ) ); System.out.println( Math.floorMod( 11 , 2 ) ); System.out.println( Math.floorMod(- 15 , 2 ) ); System.out.println( Math.floorMod(- 16 , 2 ) ); Output: 0 1 1 0 |
同样,另一个问题可能是获取时钟的时针位置。假设当前时间是10点。您进行了n小时的调整,现在想得到它的位置。公式很简单:
Current Position = (position + adjustment) % 12
如果将(位置+调整)计算为位置编号,则效果很好。但是,如果时针逆时针旋转,从而(位置+调整)变为负数,该怎么办。让我们检查。
System.out.println( ( 10 + 3 ) % 12 ); System.out.println( ( 5 + 6 ) % 12 ); System.out.println( ( 10 - 27 ) % 12 ); Output: 1 11 - 5 //This is incorrect |
现在,使用精确的空中方法floorMod
。
System.out.println( Math.floorMod( 10 + 3 , 12 ) ); System.out.println( Math.floorMod( 5 + 6 , 12 ) ); System.out.println( Math.floorMod( 10 - 27 , 12 ) ); Output: 1 11 7 //This is correct |
floorDiv()
方法上也进行了类似的更改。
3)toIntExact方法
当您尝试为int类型变量分配一个long值时,此方法很方便。尽管这种情况并非易事,但在极少数情况下可能会需要。如果long值大于最大int值,则正常的long到int转换会导致数据错误。toIntExact()
如果发生这种情况,该方法将引发异常。
System.out.println( Long.MAX_VALUE ); System.out.println( ( int )Long.MAX_VALUE ); System.out.println( Math.toIntExact(10_00_00_000) ); System.out.println( Math.toIntExact(Long.MAX_VALUE) ); Output: 9223372036854775807 - 1 100000000 Exception in thread "main" java.lang.ArithmeticException: integer overflow at java.lang.Math.toIntExact(Math.java: 1011 ) at java8features.MathematicalFuctions.main(MathematicalFuctions.java: 46 ) |
4)nextDown方法
这也是Java 8套件中的一个明显新增功能。当您要返回小于n的数字时,这非常有用。您计算的返回数字恰好是n。然后,您可以使用此方法查找最接近n(但仍小于n)的数字。
System.out.println( Math.nextDown( 100 ) ); System.out.println( Math.nextDown( 100.365 ) ); Output: 99.99999 100.36499999999998 |
请注意,Math.nextUp()
自Java 6以来已经存在。仅Math.nextDown()
在Java 8中添加。
就是这样。希望您喜欢阅读。您的想法和评论总是受到欢迎。
- 本文标签: 其他
- 本文链接: https://www.v8en.com/article/256
- 版权声明: 本文由SIMON原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权