有关JAVA BigDecimal的使用

本文深入探讨了Java中的BigDecimal类在不同构造函数使用下如何影响数值的精确度,特别关注从double到BigDecimal的转换过程及其可能出现的精度问题。通过实例展示了setScale函数的用法以及类型转换方法,并强调了String构造函数在确保数值精确性方面的优势。

先看段官方文档

/*The results of thisconstructor can be somewhat unpredictable. One might assume that 
new BigDecimal(.1) is exactlyequal to .1, but it is actually equal 
to.1000000000000000055511151231257827021181583404541015625. This is so because.1 
cannot be represented exactlyas a double (or, for that matter, as a binary fraction 
of any finite length). Thus,the long value that is being passed in to the constructor 
is not exactly equal to .1,appearances nonwithstanding.
The (String) constructor, onthe other hand, is perfectly predictable: new BigDecimal
(".1") is exactlyequal to .1, as one would expect. Therefore, it is generally 
recommended that the (String)constructor be used in preference to this one.*/ 


 

也就是说利用double作为参数的构造函数,无法精确构造一个BigDecimal对象,需要自己指定一个上下文的环境,也就是指定精确位。而利用String对象作为参数传入的构造函数能精确的构造出一个BigDecimal对象。

               

    BigDecimal b = newBigDecimal("0.3");  //BigDecimal b = new BigDecimal(0.3);    
                   System.out.println(b.multiply(BigDecimal.valueOf(100)));
                   System.out.println(b.floatValue()*100);
                   System.out.println(b.multiply(BigDecimal.valueOf(100)).setScale(0,BigDecimal.ROUND_HALF_UP));

 

关于setScale函数的:

setScale(1)表示保留以为小数,默认用四舍五入方式

setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3

setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4

setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4

setScaler(1,BigDecimal.ROUND_HALF_DOWN)五舍六入,2.35变成2.3,2.36变成2.40 如果是5则向下舍

关于类型转换:

BigDecimal类提供了诸如intValue(),floatValue(), doubleValue(), longValue()方法来将BigDecimal对象转换成对应的值

还提供了valueOf() 来将float,double类型转换为BigDecimal

 

网上总结:

1、此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

2、另一方面,String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法。

3、当 double 必须用作BigDecimal 的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用 Double.toString(double) 方法,然后使用BigDecimal(String) 构造方法,将 double 转换为 String。要获取该结果,请使用 static valueOf(double) 方法。


补充:

1、BigDecimal 计算时由于除法运算,得到循环结果,造成异常!

BigDecimal total = new BigDecimal(200).setScale(3, BigDecimal.ROUND_HALF_UP);

表示这个total的初始值为200.000

 

BigDecimal total2 = new BigDecimal(10).setScale(3, BigDecimal.ROUND_HALF_UP);

 

表示这个total2的初始值为10.000

 

当这个2数相除的时候不能简单的用total.divide(total2);

 

如果这样会报错:

 

Non-terminating decimal expansion; no exact representable decimal result

 

正确的方法:

 

total.divide(total2,3,BigDecimal.ROUND_HALF_UP);

 

这样才不会报错,你必须为它保留小数位


 


<think>首先,用户的问题是:"我想查找JavaBigDecimal类的min方法的使用方法 请问Java BigDecimal类min方法的使用指南"。这基于之前的引用内容,我需要参考那些引用来回答。 回顾引用: - 引用[1]:讨论BigDecimal类的基本使用,包括创建对象、算术运算、舍入操作和比较值。 - 引用[2]:展示了BigDecimal的正确使用方式,如除法的例子。 - 引用[3]:解释setScale方法,强调BigDecimal对象是不可变的。 - 引用[4]:关于char[]转String和进制转换,但似乎不直接相关。 - 引用[5]:关于Math类的示例,如绝对值、max、min等,但这不是BigDecimal特有的。 用户指定要查找BigDecimal的min方法。从引用中,引用[5]提到了Math类的min方法,但用户问的是BigDecimal类。所以,我需要回忆起BigDecimal类有min方法。 BigDecimal类确实有min方法。它返回两个BigDecimal对象中较小的那个。我需要基于引用提供指南。 关键引用: - 引用[1]提到比较值时使用equals或compareTo,避免使用==运算符。 - 引用[2]和[3]展示了BigDecimal的创建和操作。 由于引用中没有直接提到min方法,我应该基于一般知识回答,但参考相关引用。 系统指令: - 所有行内数学表达式必须用$...$。 - 独立公式用$$...$$。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识。 - 回答结构清晰,逐步解决问题。 - 引用示例:末尾加[^n]。 用户需求:BigDecimal min方法的使用指南。 步骤: 1. 介绍min方法是什么。 2. 解释如何使用。 3. 提供代码示例。 4. 强调注意事项,如不可变性(从引用[3])。 5. 比较值时的注意事项(从引用[1])。 6. 生成相关问题。 生成相关问题:基于用户查询,问题应相关,比如比较操作、其他方法等。 结构化回答: - 先简要介绍BigDecimal和min方法。 - 然后详细说明使用。 - 代码示例。 - 注意事项。 - 相关问题。 确保中文回答。 可能的注意事项: - BigDecimal是不可变的,所以min方法返回新对象(参考引用[3])。 - 比较值时使用compareTo而不是==(参考引用[1])。 - 可能涉及精度设置(参考引用[2]和[3])。 代码示例:创建两个BigDecimal对象,然后调用min方法。 例如: BigDecimal a = new BigDecimal("10.5"); BigDecimal b = new BigDecimal("10.0"); BigDecimal minValue = a.min(b); // 返回较小的那个 在回答中整合引用: - 提到创建对象时优先使用字符串构造器(引用[1])。 - 调用方法进行计算(引用[1])。 - 不可变性(引用[3])。 - 比较值的方法(引用[1])。 相关问题: 1. BigDecimal的max方法如何使用? 2. 如何处理BigDecimal的精度问题? 3. BigDecimal与其他数值类型的比较? 结束引用标识:[^1], [^3]等。 最终回答结构: 1. 介绍BigDecimal min方法。 2. 语法和使用说明。 3. 代码示例。 4. 注意事项。 5. 相关问题。 </think>### Java BigDecimal类min方法的使用指南 BigDecimal 类的 min 方法是用于比较两个 BigDecimal 对象并返回较小的值。该方法基于数值比较,而不是引用比较,确保了高精度计算的准确性。BigDecimal 对象是不可变的(即每次操作都会返回新的对象),因此调用 min 方法不会改变原始对象,而是创建一个新实例[^3]。以下是详细的使用步骤和注意事项,基于引用内容整合。 #### 1. **方法语法和基本使用** - **语法**:`public BigDecimal min(BigDecimal val)` - 参数 `val`:要与当前对象比较的另一个 BigDecimal 对象。 - 返回值:返回较小的 BigDecimal 值;如果两个值相等,则返回当前对象。 - **使用步骤**: 1. 创建 BigDecimal 对象:优先使用字符串构造器 `BigDecimal(String val)` 来避免浮点数精度问题[^1]。 2. 调用 min 方法:直接在 BigDecimal 实例上调用 min。 3. 处理结果:由于 BigDecimal 不可变,返回的结果是一个新对象,需赋值给新变量。 #### 2. **代码示例** 以下是完整的 Java 代码示例,展示了 min 方法的基本用法: ```java import java.math.BigDecimal; public class BigDecimalMinExample { public static void main(String[] args) { // 创建两个BigDecimal对象,使用优先的字符串构造器[^1] BigDecimal num1 = new BigDecimal("10.75"); BigDecimal num2 = new BigDecimal("10.50"); // 调用min方法比较值并返回较小值 BigDecimal minValue = num1.min(num2); // 打印结果 System.out.println("较小值: " + minValue); // 输出: 10.50 // 如果值相等,返回当前对象 BigDecimal num3 = new BigDecimal("10.75"); BigDecimal equalMin = num1.min(num3); System.out.println("相等时的较小值: " + equalMin); // 输出: 10.75 } } ``` #### 3. **重要注意事项** - **对象不可变性**:BigDecimal 对象一旦创建,其值不能修改。调用 min 方法会返回一个新对象,而不是修改原始对象[^3]。例如: ```java BigDecimal original = new BigDecimal("15.0"); BigDecimal result = original.min(new BigDecimal("12.5")); // 返回新对象12.5,不影响original ``` - **比较值的方式**: - 使用 min 方法进行数值比较是安全的,它内部调用 `compareTo` 方法。 - 避免使用 `==` 运算符比较 BigDecimal 值,因为它检查的是引用而非值;应使用 `compareTo` 或 `equals` 方法[^1]。例如: ```java if (minValue.compareTo(num1) <= 0) { System.out.println("minValue 小于或等于 num1"); } ``` - **精度和舍入问题**: - min 方法不涉及精度调整,但如果输入值有不同精度(如 "10.750" vs "10.75"),比较会自动处理数值相等性。 - 在涉及除法或乘法时,需单独使用 `setScale` 方法设置精度和舍入模式(如 `RoundingMode.HALF_UP`),但 min 方法本身不需要[^2][^3]。 - **性能和适用场景**:min 方法适用于财务计算、科学计算等需要高精度比较的场景,避免了浮点数误差。如果对象为 null,会抛出 NullPointerException。 #### 4. **与其他方法的对比** - **与 Math.min 的区别**:Math.min 用于基本数据类型(如 int 或 double),但 BigDecimal.min 专为高精度设计,适合十进制数。 ```java double minDouble = Math.min(10.75, 10.50); // 返回10.5,但精度较低 ``` - **与 max 方法对比**:BigDecimal 也有 max 方法,语法类似,返回较大值。 通过以上指南,您可以安全地使用 BigDecimal.min 方法进行精确数值比较。如果需要更多细节,参考 Java 官方文档或相关资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值