精确值避免使用float和double,使用BigDecimal
实现将double类型的值转换为BigDecimal类型的值的不同途径以及各途径间的区别
一:有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),
但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。
这是因为 0.1 无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。
这样,传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
二:另一方面,String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal,
它正好 等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法。
三:使用public static BigDecimal valueOf(double val)
使用 Double.toString(double) 方法提供的 double 规范的字符串表示形式将 double 转换为 BigDecimal。
这通常是将 double(或 float)转化为 BigDecimal 的首选方法, 因为返回的值等于从构造 BigDecimal(使用 Double.toString(double) 得到的结果)得到的值。
package com; import java.math.BigDecimal; /**
* Created by huyanxia on 2017/11/27.
*/
public class TestBigDecimal {
public static void main(String[] args) {
//3.0300000000000002
System.out.println(1.03 + 2);
//3.0300000000000000266453525910037569701671600341796875
System.out.println(new BigDecimal(1.03).add( new BigDecimal(2)));
//3.03
System.out.println(new BigDecimal("1.03").add( new BigDecimal("2")));
//3.03
System.out.println(BigDecimal.valueOf(new BigDecimal("1.03").add( new BigDecimal("2")).doubleValue()));
/* float和double尤其不适合进行货币计算,原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。
我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。
如:2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。浮点数的值实际上是由一个特定的数学公式计算得到的。*/ /*解决: 使用BigDecimal、int或long进行货币计算,1.BigDecimal货币计算,BigDecimal的参数要以字符串而不是double
2.以分为单位进行计算,而不是意愿为单位*/ //可以买3个,还剩0.3999999999999999元。
double funds = 1.00;
int bought = 0;
for(double price = 0.1; funds >= price; price +=0.1){
funds -= price;
bought ++;
}
System.out.println("可以买" + bought + "个,还剩" + funds +"元。"); //可以买4个,还剩0.00元。
BigDecimal TEN_CEN = new BigDecimal("0.1");
BigDecimal funds1 = new BigDecimal("1.00");
int bought1 = 0;
for(BigDecimal price = TEN_CEN; funds1.compareTo(price) >= 0; price = price.add(TEN_CEN)){
funds1 = funds1.subtract(price);
bought1 ++;
}
System.out.println("可以买" + bought1 + "个,还剩" + funds1 +"元。"); //可以买3个,还剩0.3999999999999999666933092612453037872910499572753906250元。
BigDecimal TEN_CEN2 = new BigDecimal(0.1);
BigDecimal funds2 = new BigDecimal(1.00);
int bought2 = 0;
for(BigDecimal price = TEN_CEN2; funds2.compareTo(price) >= 0; price = price.add(TEN_CEN2)){
funds2 = funds2.subtract(price);
bought2 ++;
}
System.out.println("可以买" + bought2 + "个,还剩" + funds2 +"元。"); //可以买4个,还剩0元。
int funds3 = 100;
int bought3 = 0;
for(int price = 10; funds3 >= price; price += 10){
funds3 -= price;
bought3 ++;
}
System.out.println("可以买" + bought3 + "个,还剩" + funds3 +"元。");
}
}
精确值避免使用float和double,使用BigDecimal的更多相关文章
- Char、float、Double、BigDecimal
Char初识 char: char类型是一个单一的 16 位 Unicode 字符 char 在java中是2个字节("字节"是byte,"位"是bit ,1 ...
- float、double、BigDecimal的一些精度问题
float f = 280.8f;System.out.println(f*100);结果是什么?结果是:28080.0f(我是这么想的)实际结果是:28079.998 既然float处理有问题换do ...
- 第48条:如果需要精确的答案,请避免使用float和double
float和double主要为了科学计算和工程计算而设计,执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不适合用于需要精确 ...
- decimal, float 和double
阿里的 Java 手册里写着: 6. [强制] 小数类型为 decimal,禁止使用 float 和 double. 说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的 ...
- 关于 BigDecimal处理float、double数据
Big Decimal 在java中,对于float与double中的数据,总会因为精度问题而丢失数据的准确性,也就是说对于两者所处理的得到的值是无限接近于那个数,而并非一个精确数字,而对于电商中所涉 ...
- float和double精度问题
System.out.println(new BigDecimal(253.90).doubleValue() * 100);25390.0精度正确 System.out.println(new Bi ...
- Effective Java 48 Avoid float and double if exact answers are required
Reason The float and double types are particularly ill-suited for monetary calculations because it i ...
- Decimal、 Float、 Double 使用
一.Java 1.float型定义的数据末尾必须 有"f "或"F",为了和double区别.例float x=123.456f, y=2e20f; publ ...
- java float、double精度研究(转)
在java中运行一下代码System.out.println(2.00-1.10);输出的结果是:0.8999999999999999很奇怪,并不是我们想要的值0.9 再运行如下代码:System.o ...
随机推荐
- ArrayList 除重
看到一段简洁的 ArrayList 除重代码: protected final <T> List<T> removeDuplicates(List<T> list) ...
- C++反射实现(转)
参考了wxWidgets的相关代码,并进行简化,同时借鉴了网上的相关内容,改进之处在于,只需要继承基本类Object,在类的头文件中定义宏,DECLARE_CLASS(类名),在类的实现文件中定义宏, ...
- 使用pm2-zabbix监控node工程
环境 centos 7 zabbix 3.2.6 node 4.4.3 安装 # wget http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix ...
- ORA-600 [kcblin_3] 解决方法
今日,我们一个sql在某环境执行出错,如下: ORA-00600: 内部错误代码, 参数: [kcblin_3], [103], [253952], [8192], [32769], [312], [ ...
- ORA-12801/ORA-12853: insufficient memory for PX buffers: current 274880K, max needed 19722240K/ORA-04031解决方法
近日,现场一台服务器在运行时出现下列异常: ORA-12801: error signaled in parallel query server P139 ORA-12853: insufficien ...
- resmgr:cpu quantum 等待事件 top 1
早上看昨天现场的报告,发现晚上七八点,resmgr:cpu quantum 等待事件排在i第一位,如下: 该事件是和资源管理相关的,如果启用资源管理计划,就可能遇到这个问题. 所以常规的解决方案是禁用 ...
- SVN冲突以及解决办法
1.冲突原因: 假设 A.B 两个用户都在版本号为 100 的时候,更新了 kingtuns.txt 这个文件,A 用户在修改完成之后提交 kingtuns.txt 到服务器, 这个时候提交成功,这个 ...
- 百度AI搜索引擎
一.爬虫协议 与其它爬虫不同,全站爬虫意图爬取网站所有页面,由于爬虫对网页的爬取速度比人工浏览快几百倍,对网站服务器来说压力山大,很容易造成网站崩溃. 为了避免双输的场面,大家约定,如果网站建设者不愿 ...
- ECharts上手例子
ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器 (IE8/9/10/11,Chrome,Firefox,Safari等 ...
- 使用python+hadoop-streaming编写hadoop处理程序
Hadoop Streaming提供了一个便于进行MapReduce编程的工具包,使用它可以基于一些可执行命令.脚本语言或其他编程语言来实现Mapper和 Reducer,从而充分利用Hadoop并行 ...