1.八股文:Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
答案:Math.round()
函数将一个数字四舍五入为最接近的整数。对于 Math.round(11.5)
,结果为 12
,而对于 Math.round(-11.5)
,结果为 -11
在Java中Math这个类是属于java.lang中的,在这个类中,定义了很多执行基本数值操作的方法,例如基本指数、对数、平方根和三角函数。round()就是其中一个。
The class Math contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.
2.业务中是否用到相关的方法?
搜索过往的项目中,没有直接用到Math.round()这个方法。我经历过的项目多为电商项目,其中对数值精度处理的需求往往体现在金额上。而对金额的表示,我们往往使用的是BigDecimal,而对其的精度往往是需要保留小数点后两位,这里我们常使用到的是RoundingMode。
`BigDecimal` 是Java中表示任意精度的十进制数的类。它提供了对数值进行精确计算的能力,不会由于浮点数的精度限制而导致误差。
与基本数据类型(如 `double` 或 `float`)不同,`BigDecimal` 可以表示任意大或小的数,而不会丢失精度。这对于需要高精度计算的金融、科学或工程应用程序来说非常有用。
`BigDecimal` 类具有以下特点和功能:
1. **任意精度:** `BigDecimal` 可以存储任意精度的数值,可以处理大数字和小数字,而不会丢失精度。
2. **精确计算:** 与浮点数不同,`BigDecimal` 可以进行精确的算术运算,而不会产生舍入误差。
3. **可靠舍入:** `BigDecimal` 提供了各种舍入模式,可以根据需要执行舍入操作。
4. **不可变性:** `BigDecimal` 对象是不可变的,一旦创建,就无法修改其值。
5. **支持算术运算:** `BigDecimal` 类提供了各种算术运算方法,如加法、减法、乘法、除法等。
6. **支持比较操作:** `BigDecimal` 可以进行大小比较,判断两个数值的相对大小。
使用 `BigDecimal` 类可以避免由于浮点数运算带来的精度问题,特别是在需要高精度计算或对精确度要求较高的场景下。然而,由于 `BigDecimal` 的操作相对于基本数据类型的操作而言更加耗时,因此在性能要求较高的情况下需要慎重使用。
`RoundingMode` 是 Java 中的一个枚举类,用于表示数字舍入的模式。在数值计算中,经常需要对结果进行舍入以达到特定的精度要求,`RoundingMode` 枚举类提供了一组常见的舍入模式,用于指示如何进行舍入操作。
`RoundingMode` 枚举类包含以下几种舍入模式:
1. `UP`:远离零方向的舍入,即向正无穷大舍入。
2. `DOWN`:靠近零方向的舍入,即向零舍入。
3. `CEILING`:朝正无穷大方向舍入,即向正无穷大舍入,除非结果为零,此时舍入到零。
4. `FLOOR`:朝负无穷大方向舍入,即向负无穷大舍入,除非结果为零,此时舍入到零。
5. `HALF_UP`:向最接近的整数舍入,如果距离两个最接近的整数相等,则舍入到偶数。
6. `HALF_DOWN`:向最接近的整数舍入,如果距离两个最接近的整数相等,则向下舍入。
7. `HALF_EVEN`:向最接近的整数舍入,如果距离两个最接近的整数相等,则舍入到最近的偶数。
8. `UNNECESSARY`:断言请求的操作具有精确的结果,因此不需要舍入。如果对请求的操作的结果不是精确的数值,则抛出 `ArithmeticException`。这些舍入模式提供了灵活的选择,可以根据具体的需求来决定如何舍入数值。在使用 `BigDecimal` 进行数值计算时,通常会指定舍入模式来控制计算结果的精度。
项目中对金额计算的案例:
(1).计算总金额
//reduce() 方法会遍历流中的所有元素,依次使用累加器对当前元素和累加结果进行操作,从而得到最终的累加结果,即所有商品的总价。
//reduce() 方法接受两个参数:初始值和一个 BinaryOperator 类型的累加器。在这里,初始值是 BigDecimal.ZERO,表示累加的初始值为零。累加器是 BigDecimal::add,表示对两个 BigDecimal 对象进行相加操作。
BigDecimal decimal = goodsDTOS.stream().map(ResClientOrderDetailGoodsDTO::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
(2).客单价的计算
// 客单价
if (respInfo.getOrderPriceSum() != null && respInfo.getOrderPriceSum().compareTo(new BigDecimal("0.00")) > 0) {
respInfo.setPerPrice(respInfo.getOrderPriceSum().divide(new BigDecimal(respInfo.getPayCount()), 4, RoundingMode.HALF_UP));
} else {
respInfo.setPerPrice(new BigDecimal(0.00));
}
divide()
方法的第一个参数是除数,第二个参数是小数位数,第三个参数是舍入模式(这里使用了 RoundingMode.HALF_UP
,表示四舍五入)。
这里还用到了compareTo():
`compareTo` 是 Java 中 `BigDecimal` 类的方法之一,用于比较两个 `BigDecimal` 对象的大小关系。该方法的签名为:
```java
public int compareTo(BigDecimal val)
```它返回一个整数值,指示调用对象与参数 `val` 的大小关系:
- 如果调用对象小于 `val`,则返回负整数(通常为 -1)。
- 如果调用对象等于 `val`,则返回零。
- 如果调用对象大于 `val`,则返回正整数(通常为 1)。这种比较方法是基于数值的大小关系进行的,而不是简单地比较它们的引用或内存地址。
`compareTo` 方法用于比较两个 `BigDecimal` 对象的数值大小,而不考虑它们的精度或小数点位置。因此,即使两个 `BigDecimal` 对象表示的数值相同,它们的小数位数或标度不同也会被视为不同。
使用 `compareTo` 方法可以进行数值的比较,从而在程序中实现根据数值大小来做出不同的逻辑决策。
(3).对以int表示的以分为金额的处理
调用第三方平台接口拿到的金额数据往往是用int来表示到分的,这里要处理成以元为单位,就要除以一个100
BigDecimal realPayment = BigDecimal.valueOf(productInfo.getReal_price()).divide(BigDecimal.valueOf(100));
(4).待补充