java - 为什么 BigDecimal 在 Java 中返回我的大 double 的近似值?
问题描述
我想对我的大双精度数进行舍入,所以我决定做的第一件事就是通过以下方式将其转换为 BigDecimal。
BigDecimal amount = BigDecimal
.valueOf(getAmount())
.setScale(2, RoundingMode.HALF_UP);
System.out.println(amount);
在我的示例中,getAmount()
返回123456789123123424113.31
.
因此,我希望我的代码段打印出完全相同的值。
相反,我得到以下值:
123456789123123430000.00
有人可以解释为什么 BigDecimal 返回我的双精度值的近似值吗?
解决方案
在我的示例中,
getAmount()
返回123456789123123424113.31
.
不,不是的。这不是 adouble
可以准确表示的值。
您可以使用以下代码轻松验证:
double d = 123456789123123424113.31d;
System.out.println(d);
哪个输出
1.2345678912312343E20
此值具有最少的位数,可将其与任何其他double
值唯一区分开来。这意味着 中没有更多相关的数字double
。在将值转换为BigDecimal
.
虽然整数数据类型,例如long
andint
可以精确地表示其范围内的每个(整数)值,但对于浮点数则不能这样说:它们可以表示的值范围很广,但代价是不能够表示范围内的每个可能值。实际上,浮点数可以表示的位数是有限的(大约 16 个十进制数字double
和大约 7 个十进制数字float
)。其他一切都将被切断。
如果您需要任意精度,那么类似的东西BigDecimal
会有所帮助:它将分配尽可能多的内存来保存所有数字(或根据您的规范四舍五入,如果需要),使其更复杂但也更强大。
BigDecimal bd = new BigDecimal("123456789123123424113.31");
System.out.println(bd);
将打印
123456789123123424113.31
确保不要BigDecimal
从一个double
值初始化,因为即使那样你也只会得到截止值。
推荐阅读
- powershell - 构建 IP 地址列表
- python - 调用函数的参数并获取文件哈希
- java - 在另一个线程上获取 ReentrantReadWriteLock.ReadLock 时调用对象的同步方法
- excel - 清除数据时如何避免 VLOOKUP 错误 1004?
- plot - 字数和情绪图
- python - 正则表达式向量
- selenium-webdriver - 使用 Selenium Python 处理窗口
- android - Android - 在使用带有导航组件的 CollapsingToolbar 时自定义处理导航
- iis - IIS 与任务管理器的内存消耗
- excel - 在 Excel 中修剪空格而不丢失格式