1、BigDecimal 超过两位小数,四舍五入保留两位,否则有几位有效小数保留几位
在Java中,如果你想要对BigDecimal
值进行四舍五入,但仅当小数位数超过两位时才进行,否则保留其原始小数位数,你可以编写一个方法来检查小数位数并相应地应用setScale
方法。以下是一个实现这一逻辑的示例:
import java.math.BigDecimal;
import java.math.RoundingMode;public class BigDecimalRounding {public static void main(String[] args) {// 示例数据BigDecimal number1 = new BigDecimal("123.456");BigDecimal number2 = new BigDecimal("123.45");BigDecimal number3 = new BigDecimal("123");BigDecimal number4 = new BigDecimal("123.0001"); // 测试刚好四位小数,但末位是1,应四舍五入为.00// 处理四舍五入逻辑BigDecimal processedNumber1 = roundIfMoreThanTwoDecimalPlaces(number1);BigDecimal processedNumber2 = roundIfMoreThanTwoDecimalPlaces(number2);BigDecimal processedNumber3 = roundIfMoreThanTwoDecimalPlaces(number3);BigDecimal processedNumber4 = roundIfMoreThanTwoDecimalPlaces(number4);// 输出结果System.out.println("Original: " + number1 + ", Processed: " + processedNumber1);System.out.println("Original: " + number2 + ", Processed: " + processedNumber2);System.out.println("Original: " + number3 + ", Processed: " + processedNumber3);System.out.println("Original: " + number4 + ", Processed: " + processedNumber4);}public static BigDecimal roundIfMoreThanTwoDecimalPlaces(BigDecimal value) {// 获取小数部分的长度int scale = value.scale();// 如果小数位数大于2,则四舍五入到两位小数if (scale > 2) {return value.setScale(2, RoundingMode.HALF_UP);} else {// 否则,返回原始值(注意:这里实际上可以直接返回value,因为值没有改变)return value;}}
}
然而,需要注意的是,BigDecimal
的scale()
方法返回的是数值中小数点后的位数,但它不会考虑尾随的零。例如,对于123.00
,scale()
将返回2
,尽管这些是小数点后的零。但在我们的例子中,由于我们只对超过两位小数的情况感兴趣,所以这不是问题。
对于number4
(即123.0001
),虽然它看起来像是有四位小数,但末位是1,所以根据四舍五入的规则,它应该被舍入为123.00
(在这个特定的例子中,由于我们是在检查是否“超过”两位小数,并且只在小数位数确实多于两位时才进行舍入,所以结果仍然是123.00
,尽管这看起来像是没有改变,但实际上是因为原始值的最后一位小数小于5)。然而,重要的是要理解这里的逻辑:只有当小数位数严格大于2时,我们才进行舍入。
输出结果为:
Original: 123.456, Processed: 123.46
Original: 123.45, Processed: 123.45
Original: 123, Processed: 123
Original: 123.0001, Processed: 123.00
如你所见,只有number1
被四舍五入,而其他值保持不变(尽管number4
在显示时可能看起来像是没有改变,但逻辑上是正确的,因为我们没有增加或减少其有效小数位数)。
2、去除末尾的0
在Java中,BigDecimal
类提供了stripTrailingZeros()
方法,该方法用于去除BigDecimal
值末尾不必要的零。这个方法不会改变BigDecimal
的值(在数值上),但会返回一个数值上相等但可能具有不同字符串表示的新BigDecimal
实例。
以下是一个使用stripTrailingZeros()
方法的示例:
/*** 超过两位小数,四舍五入保留两位,否则有几位有效小数保留几位* BigDecimal 去除末尾的0** @param value* @return*/public static BigDecimal roundIfMoreThanTwoDecimalPlaces(BigDecimal value) {if (value == null) {return null;}// 获取小数部分的长度int scale = value.scale();// 如果小数位数大于2,则四舍五入到两位小数if (scale > 2) {value = value.setScale(2, RoundingMode.HALF_UP);}return value.stripTrailingZeros();}
输出结果为:
@Testpublic void testRoundIfMoreThanTwoDecimalPlaces() {// 示例数据BigDecimal number1 = new BigDecimal("123.456");BigDecimal number2 = new BigDecimal("123.45");BigDecimal number3 = new BigDecimal("123.000000000");BigDecimal number4 = new BigDecimal("123.0001"); // 测试刚好四位小数,但末位是1,应四舍五入为.00// 处理四舍五入逻辑BigDecimal processedNumber1 = BigDecimalUtil.roundIfMoreThanTwoDecimalPlaces(number1);BigDecimal processedNumber2 = BigDecimalUtil.roundIfMoreThanTwoDecimalPlaces(number2);BigDecimal processedNumber3 = BigDecimalUtil.roundIfMoreThanTwoDecimalPlaces(number3);BigDecimal processedNumber4 = BigDecimalUtil.roundIfMoreThanTwoDecimalPlaces(number4);// 输出结果System.out.println("Original: " + number1 + ", Processed: " + processedNumber1);System.out.println("Original: " + number2 + ", Processed: " + processedNumber2);System.out.println("Original: " + number3 + ", Processed: " + processedNumber3);System.out.println("Original: " + number4 + ", Processed: " + processedNumber4);}
Original: 123.456, Processed: 123.46
Original: 123.45, Processed: 123.45
Original: 123.000000000, Processed: 123
Original: 123.0001, Processed: 123
如你所见,stripTrailingZeros()
方法去除了BigDecimal
值末尾的零,并且原始值和去除零后的值在数值上是相等的。
需要注意的是,stripTrailingZeros()
方法仅去除末尾的“不必要的”零。如果BigDecimal
值表示的是一个整数(即小数点后没有数字),并且末尾有零(这些零实际上是整数部分的一部分,而不是小数部分末尾的零),那么这些零将不会被去除。例如,new BigDecimal("100").stripTrailingZeros()
仍然会返回100
,因为这里的零是整数部分的一部分。
--end--