当前位置: 首页 > news >正文

Java BigDecimal 详解

目录

一、BigDecimal

1、简介

2、构造器描述 

3、方法描述 

4、使用


一、BigDecimal

        float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦。

为什么要用BigDecimal?

请看下面代码

	public static void main(String[] args) {System.out.println(0.2 + 0.1);System.out.println(0.3 - 0.1);System.out.println(0.2 * 0.1);System.out.println(0.3 / 0.1);}

运行结果:

0.30000000000000004
0.19999999999999998
0.020000000000000004
2.9999999999999996

        你认为你看错了,但结果却是是这样的。问题在哪里呢?原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。

注:根本原因是:十进制值通常没有完全相同的二进制表示形式;十进制数的二进制表示形式可能不精确。只能无限接近于那个值。

        我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。如:2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。浮点数的值实际上是由一个特定的数学公式计算得到的。

          其实java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

1、简介

        Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

2、构造器描述 

BigDecimal(int)       创建一个具有参数所指定整数值的对象。 
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 //不推荐使用
BigDecimal(long)    创建一个具有参数所指定长整数值的对象。 
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。//推荐使用

3、方法描述 

add(BigDecimal)          BigDecimal对象中的值相加,然后返回这个对象。 
subtract(BigDecimal)     BigDecimal对象中的值相减,然后返回这个对象。 
multiply(BigDecimal)     BigDecimal对象中的值相乘,然后返回这个对象。 
divide(BigDecimal)       BigDecimal对象中的值相除,然后返回这个对象。 
toString()               将BigDecimal对象的数值转换成字符串。 
doubleValue()            将BigDecimal对象中的值以双精度数返回。 
floatValue()             将BigDecimal对象中的值以单精度数返回。 
longValue()              将BigDecimal对象中的值以长整数返回。 
intValue()               将BigDecimal对象中的值以整数返回。

为什么BigDecimal(double)  不推荐使用?

	public static void main(String[] args) {BigDecimal intStr = new BigDecimal("22");BigDecimal doubleStr = new BigDecimal(1.111111111);System.out.println(intStr);System.out.println(doubleStr);}

运行结果:

22
1.111111111000000040149870983441360294818878173828125

看上面代码运行结果,你就应该知道为什么不推荐使用了,因为用这种方式也会导致计算有问题,

为什么会出现这种情况呢?

 JDK的描述:

        1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在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构造方法

        当double必须用作BigDecimal的源时,请使用Double.toString(double)转成String,然后使用String构造方法,或使用BigDecimal的静态方法valueOf,如下

	public static void main(String[] args) {BigDecimal intStr = BigDecimal.valueOf(3.66666);BigDecimal doubleStr = new BigDecimal(Double.toString(3.666666));System.out.println(intStr);System.out.println(doubleStr);}

运行结果:

3.66666
3.666666

4、使用

基本的加减乘除

	public static void main(String[] args) {BigDecimal a = new BigDecimal(36);BigDecimal b = new BigDecimal("12");System.out.println("a + b =" + a.add(b));System.out.println("a - b =" + a.subtract(b));System.out.println("a * b =" + a.multiply(b));System.out.println("a / b =" + a.divide(b));}

注意:

如果进行除法运算的时候,结果不能整除,有余数,这个时候会报java.lang.ArithmeticException,这边我们要避免这个错误产生,在进行除法运算的时候,针对可能出现的小数产生的计算,必须要多传两个参数

divide(BigDecimal,保留小数点后几位小数,舍入模式)

舍入模式

ROUND_CEILING //向正无穷方向舍入
ROUND_DOWN    //向零方向舍入
ROUND_FLOOR   //向负无穷方向舍入
ROUND_HALF_DOWN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
ROUND_HALF_EVEN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
ROUND_HALF_UP   //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6,也就是我们常说的“四舍五入”
ROUND_UNNECESSARY  //计算结果是精确的,不需要舍入模式
ROUND_UP    //向远离0的方向舍入

java.math.RoundingMode中例子放到html中

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<table border><caption><b>Summary of Rounding Operations Under Different Rounding Modes</b></caption><tr><th></th><th colspan=8>Result of rounding input to one digit with the givenrounding mode</th><tr valign=top><th>Input Number</th><th>{@code UP}</th><th>{@code DOWN}</th><th>{@code CEILING}</th><th>{@code FLOOR}</th><th>{@code HALF_UP}</th><th>{@code HALF_DOWN}</th><th>{@code HALF_EVEN}</th><th>{@code UNNECESSARY}</th><tr align=right><td>5.5</td>  <td>6</td>  <td>5</td>    <td>6</td>    <td>5</td>  <td>6</td>      <td>5</td>       <td>6</td>       <td>throw {@code ArithmeticException}</td><tr align=right><td>2.5</td>  <td>3</td>  <td>2</td>    <td>3</td>    <td>2</td>  <td>3</td>      <td>2</td>       <td>2</td>       <td>throw {@code ArithmeticException}</td><tr align=right><td>1.6</td>  <td>2</td>  <td>1</td>    <td>2</td>    <td>1</td>  <td>2</td>      <td>2</td>       <td>2</td>       <td>throw {@code ArithmeticException}</td><tr align=right><td>1.1</td>  <td>2</td>  <td>1</td>    <td>2</td>    <td>1</td>  <td>1</td>      <td>1</td>       <td>1</td>       <td>throw {@code ArithmeticException}</td><tr align=right><td>1.0</td>  <td>1</td>  <td>1</td>    <td>1</td>    <td>1</td>  <td>1</td>      <td>1</td>       <td>1</td>       <td>1</td><tr align=right><td>-1.0</td> <td>-1</td> <td>-1</td>   <td>-1</td>   <td>-1</td> <td>-1</td>     <td>-1</td>      <td>-1</td>      <td>-1</td><tr align=right><td>-1.1</td> <td>-2</td> <td>-1</td>   <td>-1</td>   <td>-2</td> <td>-1</td>     <td>-1</td>      <td>-1</td>      <td>throw {@code ArithmeticException}</td><tr align=right><td>-1.6</td> <td>-2</td> <td>-1</td>   <td>-1</td>   <td>-2</td> <td>-2</td>     <td>-2</td>      <td>-2</td>      <td>throw {@code ArithmeticException}</td><tr align=right><td>-2.5</td> <td>-3</td> <td>-2</td>   <td>-2</td>   <td>-3</td> <td>-3</td>     <td>-2</td>      <td>-2</td>      <td>throw {@code ArithmeticException}</td><tr align=right><td>-5.5</td> <td>-6</td> <td>-5</td>   <td>-5</td>   <td>-6</td> <td>-6</td>     <td>-5</td>      <td>-6</td>      <td>throw {@code ArithmeticException}</td>
</table>
</body>
</html>

需要对BigDecimal进行截断和四舍五入可用setScale方法,例:

	public static void main(String[] args) {BigDecimal a = new BigDecimal("2.3366");a = a.setScale(2, RoundingMode.HALF_UP);System.out.println(a);}

运行结果:2.34



原文链接:https://blog.csdn.net/qq_35868412/article/details/89029288

无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

相关文章:

Java BigDecimal 详解

目录 一、BigDecimal 1、简介 2、构造器描述 3、方法描述 4、使用 一、BigDecimal float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算&#xff0c;这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而&#xff0c;它…...

简述信息论与采样定理

信息论 香农信息论发表于1948/1949年&#xff0c;它由三部分组成&#xff1a;信号采样、信源编码、信道编码&#xff1b; 信号采样&#xff1a;采样理论研究在何种条件下对连续信号进行采样&#xff0c;从而得到的离散型号可以可逆地恢复出采样前的连续信号。采样得到的离散实…...

网络安全之网站常见的攻击方式

这是作者自学的哈&#xff0c;不算课程内容。 网页中出现大量黑链 网站看着很正常&#xff0c;但是会隐藏一些链接。网页的链接几乎都是标签&#xff0c;这种黑链就是通过链接标签<a></a>或者script在里面链入恶意脚本&#xff0c;等待浏览者的访问&#xff0c;通…...

iOS Swift 拍照识别数字(Recognizing Text in Images)

可以用腾讯云 OCR的iOS demo - 腾讯云 苹果官方的解决方案&#xff08;识别度太低&#xff09; Recognizing Text in Images - apple developer Extracting phone numbers from text in images(Sample Code) - apple developer import UIKit import Visionclass ViewContro…...

数学建模:智能优化算法及其python实现

数学建模:智能优化算法及其python实现 智能优化算法简介差分进化算法(Differential Evolution,DE)遗传算法(Genetic Algorithm,GA)粒子群优化算法(Particle Swarm Optimization,PSO)模拟退火算法(Simulated Annealing,SA)蚁群算法(Ant Colony Optimization,ACO)…...

monkeyrunner环境搭建和初步用法

一、打开模拟器 运行monkeyrunner之前必须先运行相应的模拟器&#xff0c;不然monkeyrunner无法连接设备。 用Elipse打开Android模拟器或在CMD中用Android命令打开模拟器。这里重点讲一下在CMD中用Android命令打开模拟器 命令&#xff1a;emulator -avd test &#xff08;注…...

2024华为校招面试真题汇总及其解答(一)

1. 我问你点java基础的问题吧,你平时都用什么集合啊,都什么情况下使用 在 Java 中,常用的集合有以下几种: List:有序集合,可以重复,常用实现类有 ArrayList、LinkedList、Vector。Set:无序集合,不能重复,常用实现类有 HashSet、TreeSet。Map:键值对集合,键不能重复…...

css调整字体间距 以及让倾斜字体

调整字体间距 .element {letter-spacing: 2px; /* 调整为适当的值 */ }倾斜字体1 .element {font-style: italic; }请注意&#xff0c;不是所有的字体都有斜体样式可用。如果字体本身没有斜体版本&#xff0c;则可能无法实现完全的斜体效果。 倾斜字体2 <span class"…...

工具篇 | Gradle入门与使用指南 - 附Github仓库地址

介绍 1.1 什么是Gradle&#xff1f; Gradle是一个开源构建自动化工具&#xff0c;专为大型项目设计。它基于DSL&#xff08;领域特定语言&#xff09;编写&#xff0c;该语言是用Groovy编写的&#xff0c;使得构建脚本更加简洁和强大。Gradle不仅可以构建Java应用程序&#x…...

使用 Python 函数callable和isinstance的意义

一、说明 在这篇博客中&#xff0c;我们将探讨两个python函数&#xff1a;1 callable 中的函数及其有趣的应用程序。该callable函数用于检查对象是否可调用&#xff0c;这意味着它可以作为函数调用。2 isinstance这个内置函数允许我们比较两种不同的数据类型并确定它们是否相…...

Netty场景及其原理

Netty场景及其原理 Netty简化Java NIO的类库的使用&#xff0c;包括Selector、 ServerSocketChannel、 SocketChannel、ByteBuffer&#xff0c;解决了断线重连、 网络闪断、心跳处理、半包读写、 网络拥塞和异常流的处理等。Netty拥有高性能、 吞吐量更高&#xff0c;延迟更低…...

Java接口和接口继承

Java接口和接口继承 接口 在抽象类中&#xff0c;抽象方法本质上是定义接口规范&#xff0c;即规定高层类的接口&#xff0c;从而保证所有子类都有相同的接口实现&#xff0c;这样&#xff0c;多态就能发挥出威力。 如果一个抽象类没有字段&#xff0c;所有方法全部都是抽象方…...

2023 年解锁网络安全即服务

在当今快速发展的数字世界中&#xff0c;强大的网络安全机制的重要性怎么强调都不为过。对于越来越多地发现自己成为网络威胁焦点的小型企业来说尤其如此。 那么&#xff0c;“网络安全即服务”到底是什么&#xff1f;为什么它对小型企业至关重要&#xff1f; 网络安全即服务…...

python基于轻量级卷积神经网络模型GhostNet开发构建养殖场景下生猪行为识别系统

养殖业的数字化和智能化是一个综合应用了互联网、物联网、人工智能、大数据、云计算、区块链等数字技术的过程&#xff0c;旨在提高养殖效率、提升产品质量以及促进产业升级。在这个过程中&#xff0c;养殖生猪的数字化智能化可以识别并管理猪的行为。通过数字化智能化系统&…...

Selenium自动化测试 —— 通过cookie绕过验证码的操作!

验证码的处理 对于web应用&#xff0c;很多地方比如登录、发帖都需要输入验证码&#xff0c;类型也多种多样&#xff1b;登录/核心操作过程中&#xff0c;系统会产生随机的验证码图片&#xff0c;进行验证才能进行后续操作 解决验证码的方法如下&#xff1a; 1、开发做个万能…...

链表(单链表、双链表)

前言&#xff1a;链表是算法中比较难理解的部分&#xff0c;本博客记录单链表、双链表学习&#xff0c;理解节点和指针的使用&#xff0c;主要内容包括&#xff1a;使用python创建链表、实现链表常见的操作。 目录 单链表 双链表 单链表 引入链表的背景&#xff1a; 先来看…...

面试题08.05.递归算法

递归乘法。 写一个递归函数&#xff0c;不使用 * 运算符&#xff0c; 实现两个正整数的相乘。可以使用加号、减号、位移&#xff0c;但要吝啬一些。 示例1: 输入&#xff1a;A 1, B 10输出&#xff1a;10示例2: 输入&#xff1a;A 3, B 4输出&#xff1a;12提示: 保证乘法…...

分布式IT监控系统

公司的IT系统越来越复杂&#xff0c;对运维和维护服务的需求也越来越高。在这种环境下&#xff0c;分布式IT监控系统应运而生。它逐渐成为公司提高运营效率、保证业务高效运营的关键工具&#xff0c;功能强大&#xff0c;性能优良。 分布式IT监控系统是什么&#xff1f; 分布…...

Redis 是什么?

Redis是一种基于内存的数据库&#xff0c;数据的读写都是在内存中完成的&#xff0c;因此读写速度非常的快&#xff0c;常用于缓存&#xff0c;消息队列&#xff0c;分布式锁等场景。 Redis 在高并发项目中&#xff0c;担任着非常重要的作用&#xff0c;扛高并发的&#xff0c;…...

本地源制作

title: 本地源制作 createTime: 2020-10-29 18:05:52 updateTime: 2020-10-29 18:05:52 categories: linuxyum tags: 制作本地源 通过 createrepo 制作本地源 前提 : 前提制作本地源的机器可以安装 这个软件例如 下载nginx的时候 自己加上 nginx的yum的数据源 &#xff08;rp…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...