千家信息网

如何总结Java中BigDecimal类与int、Integer使用

发表于:2024-11-11 作者:千家信息网编辑
千家信息网最后更新 2024年11月11日,这篇文章给大家介绍如何总结Java中BigDecimal类与int、Integer使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言我们都知道浮点型变量在进行计算的时候会出现
千家信息网最后更新 2024年11月11日如何总结Java中BigDecimal类与int、Integer使用

这篇文章给大家介绍如何总结Java中BigDecimal类与int、Integer使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

前言

我们都知道浮点型变量在进行计算的时候会出现丢失精度的问题。如下一段代码:

System.out.println(0.05 + 0.01);System.out.println(1.0 - 0.42);System.out.println(4.015 * 100);System.out.println(123.3 / 100);输出:0.0600000000000000050.5800000000000001401.499999999999941.2329999999999999

可以看到在Java中进行浮点数运算的时候,会出现丢失精度的问题。那么我们如果在进行商品价格计算的时候,就会出现问题。很有可能造成我们手中有0.06元,却无法购买一个0.05元和一个0.01元的商品。因为如上所示,他们两个的总和为0.060000000000000005。这无疑是一个很严重的问题,尤其是当电商网站的并发量上去的时候,出现的问题将是巨大的。可能会导致无法下单,或者对账出现问题。所以接下来我们就可以使用Java中的BigDecimal类来解决这类问题。

Java中float的精度为6-7位有效数字。double的精度为15-16位

API

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

BigDecimal精度也丢失

我们在使用BigDecimal时,使用它的BigDecimal(String)构造器创建对象才有意义。其他的如BigDecimal b = new BigDecimal(1)这种,还是会发生精度丢失的问题。如下代码:

BigDecimal a = new BigDecimal(1.01);BigDecimal b = new BigDecimal(1.02);BigDecimal c = new BigDecimal("1.01");BigDecimal d = new BigDecimal("1.02");System.out.println(a.add(b));System.out.println(c.add(d));输出:2.03000000000000002664535259100375697016716003417968752.03

可见论丢失精度BigDecimal显的更为过分。但是使用Bigdecimal的BigDecimal(String)构造器的变量在进行运算的时候却没有出现这种问题。 究其原因计算机组成原理里面都有,它们的编码决定了这样的结果。long可以准确存储19位数字,而double只能准备存储16位数字。double由于有exp位,可以存16位以上的数字,但是需要以低位的不精确作为代价。如果需要高于19位数字的精确存储,则必须用BigInteger来保存,当然会牺牲一些性能。所以我们一般使用BigDecimal来解决商业运算上丢失精度的问题的时候,声明BigDecimal对象的时候一定要使用它构造参数为String的类型的构造器。

同时这个原则Effective Java和MySQL必知必会中也都有提及。float和double只能用来做科学计算和工程计算。商业运算中我们要使用BigDecimal。

正确运用BigDecimal

BigDecimal BigDecimal(double d); //不允许使用

BigDecimal BigDecimal(String s); //常用,推荐使用

static BigDecimal valueOf(double d); //常用,推荐使用

其原因有

double 参数的构造方法,不允许使用!!!!因为它不能精确的得到相应的值; String 构造方法是完全可预知的: 写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的0.1; 因此,通常建议优先使用 String 构造方法; 静态方法 valueOf(doubleval) 内部实现,仍是将 double 类型转为 String 类型; 这通常是将 double(或float)转化为 BigDecimal 的首选方法;

BigDecimal 的大小比较

例子:a.compareTo(b) < 0

compareTo 返回: -1,0,1

-1 小于

0 等于 1 大于

BigDecimal 的小数点后位数

BigDecimal c = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_UP);System.out.println(c);//2.23 跟上面相反,进位处理----------ROUND_CEILING 天花板(向上):正数进位向上,负数舍位向上BigDecimal f = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_CEILING);System.out.println(f);//2.23 如果是正数,相当于BigDecimal.ROUND_UPBigDecimal g = new BigDecimal("-2.225667").setScale(2, BigDecimal.ROUND_CEILING);System.out.println(g);//-2.22 如果是负数,相当于BigDecimal.ROUND_DOWN----------ROUND_FLOOR 地板(向下):正数舍位向下,负数进位向下BigDecimal h = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_FLOOR);System.out.println(h);//2.22 如果是正数,相当于BigDecimal.ROUND_DOWNBigDecimal i = new BigDecimal("-2.224667").setScale(2, BigDecimal.ROUND_FLOOR);----------ROUND_HALF_UPBigDecimal d = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_UP);System.out.println("ROUND_HALF_UP"+d); //2.23 四舍五入(若舍弃部分>=.5,就进位)----------ROUND_HALF_DOWNBigDecimal e = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_DOWN);System.out.println("ROUND_HALF_DOWN"+e);//2.22 四舍五入(若舍弃部分>.5,就进位)----------

int和Integer的区别

int是java提供的8种原始类型之一,java为每个原始类型提供了封装类,Integer是int的封装类。int默认值是0,而Integer默认值是null; int和Integer(无论是否new)比较,都为true, 因为会把Integer自动拆箱为int再去比; Integer是引用类型,用==比较两个对象,其实比较的是它们的内存地址,所以不同的Integer对象肯定是不同的; 但是对于Integer i=,java在编译时会将其解释成Integer i=Integer.valueOf();。但是,Integer类缓存了[-128,127]之间的整数, 所以对于Integer i1=127;与Integer i2=127; 来说,i1==i2,因为这二个对象指向同一个内存单元。 而Integer i1=128;与Integer i2=128; 来说,i1==i2为false。

各自的应用场景

Integer默认值是null,可以区分未赋值和值为0的情况。比如未参加考试的学生和考试成绩为0的学生 加减乘除和比较运算较多,用int 容器里推荐用Integer。 对于PO实体类,如果db里int型字段允许null,则属性应定义为Integer。 当然,如果系统限定db里int字段不允许null值,则也可考虑将属性定义为int。 对于应用程序里定义的枚举类型, 其值如果是整形,则最好定义为int,方便与相关的其他int值或Integer值的比较 Integer提供了一系列数据的成员和操作,如Integer.MAX_VALUE,Integer.valueOf(),Integer.compare(),compareTo(),不过一般用的比较少。建议,一般用int类型,这样一方面省去了拆装箱,另一方面也会规避数据比较时可能带来的bug。

关于如何总结Java中BigDecimal类与int、Integer使用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

对象 问题 精度 类型 时候 方法 数字 运算 正数 精确 整数 负数 构造器 存储 推荐 不同 原始 四舍五入 两个 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 搭建一个文件下载服务器需要带宽 云服务器存储格式如何选择 西方国家使用互联网科技情报 php 连续发送两个数据库 福建三木网络技术有限公司 服务器guest账号无法删除 防城港在线网络技术有限公司招聘 大学生网络安全信息素养问卷 日文翻译服务器 高专选计算机网络技术好吗 计算机网络技术专业发展途径 建立信贷数据库 软件开发团队的绩效制定 一把手谈网络安全 软件开发流量考核指标有哪些 cov32串口服务器 品牌 服务器绑定二级域名 中国电信通信网络安全监督局 电脑连接服务器请稍后再试 软件开发占多少比例 火爆服务器的节目 ios 数据库字段类型 软件开发上海平均工资 无主之地3应该加速哪个服务器 怎么取消网络安全密码 全国网络安全知识竞赛第四期 ios基础服务器 数据库广东海洋大学 网络安全事件的紧急预案 国家网络安全检测平台
0