JavaSE——常用API进阶二(2/8)-BigDecimal(BigDecimal的常见构造器、常用方法,用法示例,使用规范)

简介: JavaSE——常用API进阶二(2/8)-BigDecimal(BigDecimal的常见构造器、常用方法,用法示例,使用规范)

在进行浮点型运算时,直接使用“ + - * / ”可能会出现运算结果失真,例如:

System.out.println(0.1 + 0.2);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);

运行结果:



诸如这些情况,就是出现了结果失真的问题。

BigDecimal类就是为了解决这个问题的。

BigDecimal

  • 用于解决浮点型运算时,出现结果失真的问题。

BigDecimal的常见构造器、常用方法

构造器 说明
public BigDecimal(double val) 注意:不推荐使用这个 将double转换为BigDecimal
public BigDecimal(String val) 把string转成BigDecimal

图片.png

用法示例

public class Test {
    public static void main(String[] args) {
        double a = 0.1;
        double b = 0.2;
//        BigDecimal a1 = new BigDecimal(Double.toString(a));
//        BigDecimal b1 = new BigDecimal(Double.toString(b));
        //推荐使用以下方式,把小数转换成字符串再得到BigDecimal对象来使用(更简洁)
        BigDecimal a1 = BigDecimal.valueOf(a);
        BigDecimal b1 = BigDecimal.valueOf(b);
 
        BigDecimal c1 = a1.add(b1);
        System.out.println(c1);
 
    }
}

运行结果:


(没有出现运算结果失真)

其他方法

public class Test {
    public static void main(String[] args) {
        double a = 0.1;
        double b = 0.2;
//        BigDecimal a1 = new BigDecimal(Double.toString(a));
//        BigDecimal b1 = new BigDecimal(Double.toString(b));
        //推荐使用以下方式,把小数转换成字符串再得到BigDecimal对象来使用(更简洁)
        BigDecimal a1 = BigDecimal.valueOf(a);
        BigDecimal b1 = BigDecimal.valueOf(b);
 
        BigDecimal c1 = a1.add(b1);
        System.out.println(c1);
 
        BigDecimal c2 = a1.subtract(b1); //减法
        BigDecimal c3 = a1.multiply(b1); //乘法
        BigDecimal c4 = a1.divide(b1);  //除法
 
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
 
    }
}

运行结果:


注意:对于除法,如果无法除尽,会因无法确定精度而报错。

public class Test {
    public static void main(String[] args) {
        BigDecimal i = BigDecimal.valueOf(0.1);
        BigDecimal j = BigDecimal.valueOf(0.3);
        BigDecimal k = i.divide(j); //除不尽
    }
}
 


解决办法:

public class Test {
    public static void main(String[] args) {
        BigDecimal i = BigDecimal.valueOf(0.1);
        BigDecimal j = BigDecimal.valueOf(0.3);
//        BigDecimal k = i.divide(j); //除不尽
        BigDecimal k = i.divide(j,2, RoundingMode.HALF_UP);  //这里的RoundingMode.HALF_UP是一个枚举类里的常量,代表四舍五入
        System.out.println(k);
    }
 
}

这样运行结果就正常了,(保留两位小数)  但是一般还是用double来解决这种问题


再来示例一下,把BigDecimal对象转换成double类型的数据

public class Test {
    public static void main(String[] args) {
        BigDecimal i = BigDecimal.valueOf(0.1);
        BigDecimal j = BigDecimal.valueOf(0.3);
//        BigDecimal k = i.divide(j); //除不尽
        BigDecimal k = i.divide(j,2, RoundingMode.HALF_UP);  //这里的RoundingMode.HALF_UP是一个枚举类里的常量,代表四舍五入
        //把BigDecimal对象转换成doubLe类型的数据
        double rs = k.doubleValue();
        System.out.println(rs);
    }
}

运行结果: 已转换为double类型


使用规范

提及其中的一点:        (取自Java开发手册)

禁止使用构造方法BigDecimal(double)的方式把double值转化为BigDecimal对象。


说明:BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。


如:BigDecimal g = new BigDecimal(0.1F);  实际的存储值为:0.10000000149

正例        优先推荐入参为String的构造方法去,或使用BigDecinal的valueOf方法,此方法内部其实执行了Double的toString,而Double的toString按double的实际能表达的精度对尾数进行了截断。


END



目录
相关文章
|
9天前
|
自然语言处理 算法 Java
地址描述转换为坐标点不使用API,有什么转换的方法?
地址描述转换为坐标点不使用API,有什么转换的方法?
180 64
|
5天前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
13天前
|
API iOS开发 开发者
Snapchat API 访问:Objective-C 实现示例
Snapchat API 访问:Objective-C 实现示例
|
2月前
|
JSON API 数据格式
python 使用 Stable Diffusion API 生成图片示例
本文提供了一个使用Python调用Stable Diffusion API生成图片的示例程序,包括启动API设置、发送POST请求、保存生成的图片和JSON数据,以及如何通过API调用特定模型的说明。
python 使用 Stable Diffusion API 生成图片示例
|
2月前
|
UED 开发工具 iOS开发
Uno Platform大揭秘:如何在你的跨平台应用中,巧妙融入第三方库与服务,一键解锁无限可能,让应用功能飙升,用户体验爆棚!
【8月更文挑战第31天】Uno Platform 让开发者能用同一代码库打造 Windows、iOS、Android、macOS 甚至 Web 的多彩应用。本文介绍如何在 Uno Platform 中集成第三方库和服务,如 Mapbox 或 Google Maps 的 .NET SDK,以增强应用功能并提升用户体验。通过 NuGet 安装所需库,并在 XAML 页面中添加相应控件,即可实现地图等功能。尽管 Uno 平台减少了平台差异,但仍需关注版本兼容性和性能问题,确保应用在多平台上表现一致。掌握正确方法,让跨平台应用更出色。
34 0
|
2月前
|
数据采集 API TensorFlow
简化目标检测流程:深入探讨TensorFlow Object Detection API的高效性与易用性及其与传统方法的比较分析
【8月更文挑战第31天】TensorFlow Object Detection API 是一项强大的工具,集成多种先进算法,支持 SSD、Faster R-CNN 等模型架构,并提供预训练模型,简化目标检测的开发流程。用户只需准备数据集并按要求处理,选择预训练模型进行微调训练即可实现目标检测功能。与传统方法相比,该 API 极大地减少了工作量,提供了从数据预处理到结果评估的一站式解决方案,降低了目标检测的技术门槛,使初学者也能快速搭建高性能系统。未来,我们期待看到更多基于此 API 的创新应用。
24 0
|
2月前
|
API 网络架构 C++
【Azure Key Vault】使用REST API调用Azure Key Vault Secret的示例步骤
【Azure Key Vault】使用REST API调用Azure Key Vault Secret的示例步骤
|
2月前
|
API 数据安全/隐私保护
【Azure Developer】使用 Microsoft Graph API 获取 AAD User 操作示例
【Azure Developer】使用 Microsoft Graph API 获取 AAD User 操作示例
|
2月前
|
JSON Java API
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
【Azure API 管理】通过Java APIM SDK创建一个新的API,如何为Reqeust的Representation设置一个内容示例(Sample)?
|
2月前
|
API
【Azure API 管理】APIM中的Policy是否有调用速率的方法(熔断机制)
【Azure API 管理】APIM中的Policy是否有调用速率的方法(熔断机制)
下一篇
无影云桌面