junit4中BigDecimal对象断言问题

本文深入探讨了使用BigDecimal处理数值精度问题的重要性,特别是针对商业计算场景。文章对比了使用double和String构造BigDecimal的区别,并强调了使用String构造方法以确保数值精度的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package test.com.xy6.interview.util;

import static org.junit.Assert.assertEquals;

import java.math.BigDecimal;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestProductUtil {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testRoundTax() {
		BigDecimal bd2 = BigDecimal.valueOf(10.10);
		BigDecimal bd3 = BigDecimal.valueOf(10.20);
		assertEquals(bd2,bd3);
	}

}

上述代码运行通过,junit版本junit4.4。

原因:初始化BigDecimal时,方法使用错误,应使用valueOf(String),而非valueOf(double)。

BigDecimal对象有两个构造函数public BigDecimal(double val),public BigDecimal(String val)。在使用double进行初始化时,转换后的数据是不精确的。如传入0.1,转换后的数据可能为.0.1000000000000000055511151231257827021181583404541015625。这是由浮点型自身的特性决定的,它并不能精确地描述一个数据。故Effective Java中建议:float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。

官方API(http://docs.oracle.com/javase/6/docs/api/index.html)中对于public BigDecimal(double val)的解释是比较清楚的:

BigDecimal

public BigDecimal(double val)
Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer.
Notes:

1 The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
2 The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
3 When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.
修改后的代码:

		BigDecimal bd2 = new BigDecimal("10.10");
		BigDecimal bd3 = new BigDecimal("10.20");
		assertEquals(bd2,bd3);
此时,测试是不通过的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值