Java8 教程

Java8 新的数学函数

Math 类提供了一些方法来进行精确的算术计算,并且当结果溢出时抛出一个异常。

multiplyExact 方法

  • static int multiplyExact(int x, int y)  返回参数的乘积,如果结果溢出 int,则抛出异常。

  • static long multiplyExact(long x, long y)  返回参数的乘积,如果结果溢出 long,则抛出异常。

例如:

int val = Math.multiplyExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
System.out.println(val);
// java.lang.ArithmeticException: integer overflow

addExact 方法

  • static int addExact(int x, int y)  返回参数之和,如果结果溢出一个 int,则抛出异常。

  • static long addExact(long x, long y)  返回参数之和,如果结果溢出 long,则抛出异常。

例如:

int val = Math.addExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
System.out.println(val);
// java.lang.ArithmeticException: integer overflow

decrementExact 方法

  • static int decrementExact(int a)  返回减一的参数,如果结果溢出一个 int,则抛出异常。

  • static long decrementExact(long a)  返回减一的参数,如果结果溢出 long,则抛出异常。

例如:

int val = Math.decrementExact(Integer.MIN_VALUE);
System.out.println(val);
// java.lang.ArithmeticException: integer overflow

incrementExact 方法

  • static int incrementExact(int a)  返回参数的增量,如果结果溢出一个 int,则抛出异常。

  • static long incrementExact(long a)  返回参数的增量,如果结果溢出 long,则抛出异常。

例如:

int val = Math.incrementExact(Integer.MAX_VALUE);
System.out.println(val);
// java.lang.ArithmeticException: integer overflow

negateExact 方法

  • static int negateExact(int a)  返回参数的否定值,如果结果溢出一个 int,则抛出异常。

  • static long negateExact(long a)  返回参数的否定值,如果结果溢出 long,则抛出异常。

例如:

int val = Math.negateExact(Integer.MIN_VALUE);
System.out.println(val);
// java.lang.ArithmeticException: integer overflow

subtractExact 方法

  • static int subtractExact(int x, int y)  返回参数的差值,如果结果溢出一个 int,则抛出异常。

  • static long subtractExact(long x, long y)  返回参数的差值,如果结果溢出 long,则抛出异常。

例如:

int val = Math.subtractExact(Integer.MIN_VALUE, 1);
System.out.println(val);
// java.lang.ArithmeticException: integer overflow

toIntExact 方法

toIntExact 方法可以将一个 long 值转换为等价的 int 值。例如:

int val = Math.toIntExact(Long.MAX_VALUE);
System.out.println(val);
// java.lang.ArithmeticException: integer overflow

floorMod 和 floorDiv 方法

Math 的 floorMod 和 floorDiv 方法旨在解决一个长期存在的整型余数问题。以表达式 n₈2 为例,如果 n 为正数,n 为偶数则结果为 0, 而 n 为奇数则结果为 1。如果 n 为负数,则结果为 -1。为什么? 当第一台计算机诞生时,先驱们不得不为如何计算负数的整除和取余制定规则。数学家在几百年前就已经知道了最佳解 (或者“欧几里得”解): 永远保持余数大于等于0。但是,这些计算机先驱没有翻阅任何一本数学教材,而是得出了一个看似合理但实际却不方便的规则。

考虑一下这个问题。你需要计算时钟上时针的位置。你打算应用一个校正值,并希望将值限定 0 到 11 之间。这很容易:(position + adjustment) % 12。但是如果校正值是负数怎么办? 那样的话你可能会得到一个负数值。因此你不得不引入一个分支,或者使用 ((position +adjustment) % 12 +12) % 12。不管是哪种方式,都很麻烦。

新的 floorMod 方法使它变得很容易:floorMod(position +adjustment,12) 总是会返回一个 0 到 11 之间的值。

方法定义如下:

  • static int floorDiv(int x, int y)  返回小于或等于代数商的最大(最接近正无穷大)int 值。

  • static long floorDiv(long x, long y)  返回小于或等于代数商的最大(最接近正无穷大)long 值。

  • static int floorMod(int x, int y)  回 int 参数的底面模数。

  • static long floorMod(long x, long y)  返回长形参数的底面模数。

例如:

int val = Math.floorMod(10, 3);
System.out.println("val = " + val);
// val = 1

val = Math.floorDiv(10, 3);
System.out.println("val = " + val);
// val = 3

注意,不幸的是,对于负的除数,floorMod 会返回负数结果,例如:

int val = Math.floorMod(10, -3);
System.out.println("val = " + val);
// val = -2

但是实际中很少发生这样的情况。

nextDown 方法

Math 为 double 和 float 参数定义的 nextDown 方法会返回比指定数字小、但最接近于指定数字的浮点数字。定义如下:

  • static double nextDown(double d)  返回负无穷方向上与 d 相邻的浮点数值。

  • static float nextDown(float f)  返回负无穷方向上与 f 相邻的浮点数值。

例如:

float val = Math.nextDown(10.2f);
System.out.println("val = " + val);
// val = 10.199999


说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号