Java BigDecimal和double

源码分析double和BigDecimal区别 使用 BigDecimal 进行运算的速度比使用 double 慢得多,因为 BigDecimal 需要进行更多的计算。因此,在需要高精度计算的情况下,应该使用 BigDecimal,而在需要高效计算的情况下,应该使用 double。 阅读详情

BigDecimal类

对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作。BigDecimal类的常用方法如表11-15所示。

表11-15 BigDecimal类的常用方法

序号

方    法

类型

描    述

1

public BigDecimal(double val)

构造

将double表示形式转换为BigDecimal

2

public BigDecimal(int val)

构造

将int表示形式转换为BigDecimal

3

public BigDecimal(String val)

构造

将字符串表示形式转换为BigDecimal

4

public BigDecimal add(BigDecimal augend)

普通

加法

5

public BigDecimal subtract(BigDecimalsubtrahend)

普通

减法

6

public BigDecimal multiply(BigDecimalmultiplicand)

普通

乘法

7

public BigDecimal divide(BigDecimaldivisor)

普通

除法

范例:进行四舍五入的四则运算

复制代码
    package org.lxh.demo11.numberdemo;
    import java.math.BigDecimal;
    class MyMath {
        public static double add(double d1, double d2)
    {        // 进行加法运算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.add(b2).doubleValue();
         }
        public static double sub(double d1, double d2)
    {        // 进行减法运算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.subtract(b2).doubleValue();
         }
        public static double mul(double d1, double d2)
    {        // 进行乘法运算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.multiply(b2).doubleValue();
         }
        public static double div(double d1,
    double d2,int len) {// 进行除法运算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.divide(b2,len,BigDecimal.
    ROUND_HALF_UP).doubleValue();
         }
        public static double round(double d,
    int len) {     // 进行四舍五入
    操作
             BigDecimal b1 = new BigDecimal(d);
             BigDecimal b2 = new BigDecimal(1);
            // 任何一个数字除以1都是原数字
            // ROUND_HALF_UP是BigDecimal的一个常量,
    表示进行四舍五入的操作
            return b1.divide(b2, len,BigDecimal.
    ROUND_HALF_UP).doubleValue();
         }
    }
    public class BigDecimalDemo01 {
        public static void main(String[] args) {
             System.out.println("加法运算:" +
    MyMath.round(MyMath.add(10.345,
    3.333), 1));
             System.out.println("乘法运算:" +
    MyMath.round(MyMath.mul(10.345,
    3.333), 3));
             System.out.println("除法运算:" +
    MyMath.div(10.345, 3.333, 3));
             System.out.println("减法运算:" +
    MyMath.round(MyMath.sub(10.345,
    3.333), 3));
         }
    }
复制代码

 

BigDecimal是Java中用来表示任意精确浮点数运算的类,在BigDecimal中,使用unscaledValue × 10-scale来表示一个浮点数。其中,unscaledValue是一个BigInteger,scale是一个int。从这个表示方法来看,BigDecimal只能标识有限小数,不过可以表示的数据范围远远大于double,在实际应用中基本足够了。

下面提一下两个精度问题:
 
问题一:BigDecimal的精度问题(StackOverflow上有个家伙问了相关的问题)
System.out.println(new BigDecimal(0.1).toString()); // 0.1000000000000000055511151231257827021181583404541015625
System.out.println(new BigDecimal("0.1").toString()); // 0.1
System.out.println(new BigDecimal(
Double.toString(0.1000000000000000055511151231257827021181583404541015625)).toString());// 0.1
System.out.println(new BigDecimal(Double.toString(0.1)).toString()); // 0.1

 

分析一下上面代码的问题(注释的内容表示此语句的输出)

第一行:事实上,由于二进制无法精确地表示十进制小数0.1,但是编译器读到字符串"0.1"之后,必须把它转成8个字节的double值,因此,编译器只能用一个最接近的值来代替0.1了,即0.1000000000000000055511151231257827021181583404541015625。因此,在运行时,传给BigDecimal构造函数的真正的数值是0.1000000000000000055511151231257827021181583404541015625。
第二行:BigDecimal能够正确地把字符串转化成真正精确的浮点数。
第三行:问题在于Double.toString会使用一定的精度来四舍五入double,然后再输出。会。Double.toString(0.1000000000000000055511151231257827021181583404541015625)输出的事实上是"0.1",因此生成的BigDecimal表示的数也是0.1。
第四行:基于前面的分析,事实上这一行代码等价于第三行
 
结论:
1.如果你希望BigDecimal能够精确地表示你希望的数值,那么一定要使用字符串来表示小数,并传递给BigDecimal的构造函数。
2.如果你使用Double.toString来把double转化字符串,然后调用BigDecimal(String),这个也是不靠谱的,它不一定按你的想法工作。
3.如果你不是很在乎是否完全精确地表示,并且使用了BigDecimal(double),那么要注意double本身的特例,double的规范本身定义了几个特殊的double值(Infinite,-Infinite,NaN),不要把这些值传给BigDecimal,否则会抛出异常。
 
问题二:把double强制转化成int,难道不是扔掉小数部分吗?
int x=(int)1023.99999999999999; // x=1024为什么?

原因还是在于二进制无法精确地表示某些十进制小数,因此1023.99999999999999在编译之后的double值变成了1024。

所以, 把double强制转化成int确实是扔掉小数部分,但是你写在代码中的值,并不一定是编译器生成的真正的double值。
验证代码:
double d = 1023.99999999999999;
int x = (int) d;
System.out.println(new BigDecimal(d).toString()); // 1024
System.out.println(Long.toHexString(Double.doubleToRawLongBits(d))); // 4090000000000000
System.out.println(x); // 1024

前面提过BigDecimal可以精确地把double表示出来还记得吧。

我们也可以直接打印出d的二进制形式,根据IEEE 754的规定,我们可以算出0x4090000000000000=(1024)。
JAVA BigDecimal的构造double类型 BigDecimal activePrice = new BigDecimal(4).multiply(new BigDecimal(0.01)); 开发过程中遇到的这样的问题,以上activePrice的值应该为0.04,但运行后得到的值是0.04000000000000000343434,后边有一串小数位。 百度一下知道了原因: 1、此构造方法的结果有一定的不可预知性。有人可能认 阅读详情

相关推荐

Grok AI7七大技术断层:状态感知、混合精度与可信推理实战解析

大语言模型正从‘文本生成工具’迈向‘可信赖业务协作者’,其核心演进体现在状态保持、规则执行与跨模态理解等基础能力上。传统模型受限于无状态推理、微调僵化和表格/流程图语义盲区,导致长程对话逻辑漂移、业务规则更新滞后、结构化数据误读等问题。Grok AI7通过状态图谱(LSG)、混合精度指令解码器(HPID)和跨模态语义对齐器(CMSA)等创新,实现了上下文持久化、热更规则与真懂Excel的能力。这些突破不仅提升客服、制造、政务等场景的准确率与响应效率,更支撑起可审计、可追溯、可本地化的AI落地范式。本文基于半

weixin_33842304的博客 650

BigDecimal和Double的区别

精确性:由于计算机内部使用二进制表示浮点数,而十进制小数无法精确表示为二进制,因此在进行浮点数计算时,Double会存在舍入误差。精度:BigDecimal是高精度的十进制表示,它可以表示任意精度的小数。相比之下,Double是双精度浮点数,它的精度有限,只能表示有限位数的小数。大小范围:Double的取值范围较大,可以表示较小的负数和较大的正数。运算:Double类型的数值可以直接进行加减乘除等基本运算,而BigDecimal需要使用其提供的方法进行运算,例如。

monicateacat的博客 3141

Java中金额处理选择详解:BigDecimal vs Long vs Double

特性DoubleLongBigDecimal精度不准确准确(需手动管理单位)准确范围容易溢出易溢出(但优于浮点数)几乎无限操作复杂度简单较复杂(需手动换算)丰富且灵活推荐使用场景不推荐金额处理简单金额场景金融、电商等金额计算推荐对于涉及金额的系统,优先使用BigDecimal,确保精度并降低错误风险。仅在金额简单(如无小数部分)且性能非常敏感的场景下,可考虑Long。

2401_85373732的博客 1740

探索BigDecimal和Double区别,更适合在什么条件下使用?

探索BigDecimal和Double区别,更适合在什么条件下使用?

weixin_43267639的博客 4024

【G4基础03】2.3 How to Specify Materials in the Detector

定义探测器材料

adelall的博客 489

RTDETR多模态融合实战:基于注意力机制的红外与可见光目标检测优化

本文深入探讨了基于RTDETR模型的红外与可见光多模态目标检测优化方案。针对复杂光照下的检测难题,文章提出并实战演示了如何利用注意力机制(如SimAM与交叉注意力)实现RGB与IR特征的智能动态融合,从而构建更鲁棒的“全天候”检测系统,有效提升安防、自动驾驶等场景在夜间及恶劣天气下的检测精度与可靠性。

weixin_29083373的博客 187

Java double和BigDecimal

Java double和BigDecimal 1. double package com.bigDecimalDemo.Demo01; public class Demo01 { public static void main(String[] args) { double d1 = 1.0; double d2 = 0.9; System.out.println(d1-d2); // 面试题 double res

weixin_44694641的博客 846

硬件开发实践:高速 PCB 差分信号与时钟同步优化

由两条互补信号线组成(正负极)接收端只关注两线之间电压差共模噪声对两线同时作用,可被抵消。

2501_93174775的博客 392

Java Double和BigDecimal互转

Java Double和BigDecimal互转

追求卓越583的博客 3382

深入解析数据通信中的码元速率与比特率:从基础到实战应用

本文深入解析了数据通信中的核心概念码元速率与比特率,通过生动的比喻和公式(比特率=波特率×log₂(M))揭示其本质关系。文章结合BPSK、QPSK、16QAM等调制技术,剖析了从4G/5G到LoRa等实战场景中如何权衡速率、距离与可靠性,并提供了软考真题解析与系统设计建议,帮助读者从理论到应用全面掌握数据速率优化。

weixin_29324877的博客 213

B站自动答题协议分析

使用Python写了一个自动答题机器人!基于接口协议实现且包含点选验证码识别

吴秋霖的博客 2648

Java 中的 double、Double 和 BigDecimal:深入理解

在Java中,doubleDouble和BigDecimal分别代表了原始的双精度浮点数、其包装类和高精度的十进制数。在选择使用哪个类型时,需要根据具体的场景和精度要求来做出决策。在需要精确计算的情况下,特别是涉及金融和货币计算时,推荐使用BigDecimal,以避免由于浮点数运算引起的精度问题。

My_wife_QBL的博客 2345

如何使用VNC对openEuler系统进行远程图形化操作

本文详细介绍了在openEuler系统中配置VNC远程图形化操作的方法。主要内容包括:1)服务端配置:安装GNOME图形界面和TigerVNC服务,创建VNC用户并设置密码,配置VNC服务启动脚本;2)客户端连接:使用VNC Viewer等工具连接服务器;3)常见问题解决方法。通过5901端口建立连接后,用户可远程操作openEuler图形界面,适用于需要图形化管理的场景。

2501_93651177的博客 313

Java Double转Bigdecimal丢失精度原因学习

记录学习Double转Bigdecimal丢失精度的原因 注意事项: 不能直接使用Bigdecimal的构造函数传double进行转换,部分数值会丢失精度,因为计算机是二进制的Double无法精确的储存一些小数位,0.1的double数据存储的值实际上并不真的等于0.1 如该方式将0.1转换为Bigdecimal得到的结果是 0.1000000000000000055511151231257827021181583404541015625 这是为什么呢,以往只是知道结论知道不能这么用,也大概知道是因为do

qq_35431829的博客 2853

SE模块理解+SE-Resnet模块pytorch实现

文章目录SE模块理解SE实现注意力机制原因SE-resnet网络pytorch实现定义residual定义SE模块 SE模块理解 SENet是Squeeze-and-Excitation Networks的简称,拿到了ImageNet2017分类比赛冠军,其效果得到了认可,其提出的SE模块思想简单,易于实现,并且很容易可以加载到现有的网络模型框架中。SENet主要是学习了channel之间的相关性,筛选出了针对通道的注意力,稍微增加了一点计算量,但是效果比较好。 SE模块广泛应用于去噪,去雨方向,利用SE模

qq_42754919的博客 2万+

PHP实现获取当地网络时间​(附完整源码)

PHP实现获取当地网络时间​(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 234

Java BigDecimal类的一般使用、BigDecimal转double

BigDecimal大据类。 浮点型运算的时候直接 加减乘除时可能会出现数据失真(精度问题)。 BigDecimal可以解决浮点型运算数据失真的问题。 double a = 0.1; double b = 0.2; double c = a+b; System.out.println(c);//0.30000000000000004 BigDecimal类 包: java.math. 创建一个BigDecimal对象 public stat

七七的博客 3万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Java中double转BigDecimal的注意事项

[我每次转载别人的文章不是仅仅转发一下就完事了,而是自己验证过才可以,尽信书不如无书!不过本文还未完全验证,我做项目的时候以前的程序猿用的全是Double,我用的全是BigDecimal,故产生了此需求] 先上结论:不要直接用double变量作为构造BigDecimal的参数。 线上有这么一段Java代码逻辑: 1,接口传来一个JSON串,里面有个数字:57.3。 2,解析JSON并...

假装文艺范儿 1426

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【性能】Java BigDecimal和double性能比较

  我们知道 java 里面有个 BigDecimal ,可以解决我们的精度丢失问题。 但是很少关注其性能情况,因为一般来说可以忽略不计的。 也确实,解决大数据量运算 java 本身并不适合。   本人愚笨,很早之前用 java 解决一个大数据量运算的算法,对性能要求很高。中间用了 BigDecimal ,注意到其性能的一些情况,发现其性能是 dou...

abing37的专栏 3215

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java中Double与BigDecimal的相互转换

  今天写代码过程中,发现一个Double的变量通过new BigDecimal(Double d)转换为BigDecimal时,有效数字改变了,如下: public class BigDecimalTest { public static void main(String[] arg) { String s1 = "123.45"; ...

dianmi9782的博客 2404

Java默认bigdecimal初始值_BigDecimal初始化不要用double类型

在进行单价、总价相关的计算时,就会用到BigDecimal。在初始化时,一个不小心,就可能给自己挖坑。示例如下:public class BigDecimalInitTest {public static void main(String[] args) {BigDecimal amount1=new BigDecimal("0.06");BigDecimal amount2=new BigDec...

weixin_36233098的博客 1万+

java 的double转BigDecimal的坑

大家都知道java的double由于精度问题会给你挖无数个坑,一般采取的方式都会避免使用,但是android的dbflow对model里面的BigDecimal转换为sqlite table时, field type居然是text.所以,model里面field的属性只能保持double 那么,先测试一下: double d = 3.1415; ...

rocklee的专栏 814

java double转decimal_Java中Double与BigDecimal的相互转换

今天写代码过程中,发现一个Double的变量通过new BigDecimal(Double d)转换为BigDecimal时,有效数字改变了,如下:public class BigDecimalTest {public static void main(String[] arg) {String s1 = "123.45";Double d1 = new Double(s1);     //使用S...

weixin_30072453的博客 4544

java 四舍五入new BigDecimal(double)及BigDecimal valueOf(double)的区别

最近在研究java的四舍五入,其中有一个方法如下 new BigDecimal(val).setScale(newScale, BigDecimal.ROUND_HALF_DOWN)); 其中val是要处理的浮点数 newScale表示要保留小数点后几位 BigDecimal.ROUND_HALF_DOWN表示若舍弃的部分>0.5则进位,否则直接舍弃,说白了就是五舍六入 比如说1...

野猿新一 3901
上一篇: 探秘Jps及无法查看java进程问题
下一篇: Spark 编程指南
架构师的清醒
博客等级 码龄14年 291粉丝 397原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值