文档章节

double和float计算精度不准的问题

l
 liuhao_sh
发布于 2015/08/04 11:58
字数 504
阅读 44
收藏 0

1、首先我们要知道float和double型,的底层实现是二进制的。十进制中的一个有限位数小数,转换成二进制就不一定是有限位数了,一旦位数超过的float和double型的位数宽度,就会出现“精度溢出”。所以float和double型是为了科学计算而设计的,并不适合精确的十进制计算. 

   例子: 就像一个十进制的小数,要不断地乘以2取整,但在这个过程中可能会一直循环下去,这就造成了数据的不精确。 

所以在必须要求数据的精确度时,不能使用float和double. 

public class Test{

public static void main(String[] args)

{

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.060000000000000005

0.5800000000000001

401.49999999999994

1.2329999999999999


BigDecimal类可解决计算精度问题 可使用BigDecimal类创建一个封装类。封装加减乘除操作

例:对一个小数进行指定位数的四舍五入: 

BigDecimal bd = new BigDecimal("0.9851095"); 

BigDecimal one = new BigDecimal("1"); 

System.out.println(bd.divide(one, 3, BigDecimal.ROUND_HALF_UP)); 

BigDecimal中还有很多相关的数值之间的计算方法,以及精确到的位数和四舍五入等。


注意:BigDecimal它的构造函数很多。

我挑最常用的两个 来演示一下:一个就是BigDecimal(double val),另一个就是BigDecimal(String str)。

下面是两个浮点数相减的例子来说明:
public static void main(String[] args) {
double a = 1;
double b = 0.9;
BigDecimal a1 = new BigDecimal(Double.toString(a));
BigDecimal b1 = new BigDecimal(Double.toString(b));
BigDecimal a2 = new BigDecimal(a);
BigDecimal b2 = new BigDecimal(b);
double c = a1.subtract(b1).doubleValue();
double d = a2.subtract(b2).doubleValue();
System.out.println(“c=”+c);
System.out.println(“d=”+d);
}

结果为:
c=0.1
d=0.09999999999999998

可以得出结论:

利用double作为参数的构造函数,无法精确构造一个BigDecimal对象,需要自己指定一个上下文的环境,也就是指定精确位。而利用String对象作为参数传入的构造函数能精确的构造出一个BigDecimal对象。


© 著作权归作者所有

共有 人打赏支持
l
粉丝 1
博文 83
码字总数 124777
作品 0
徐汇
私信 提问
.Net 避免 float 转 double 丢失精度的办法

第一部分:float 转 double 丢失精度 类型 精度 位宽 C# 后缀 可以表示的数值范围 .Net 类名 float 7 位 32bit F -3.4 × 10^38 ~ +3.4 × 10^38 System.Single double 15~16 位 64bit D ...

qaqz111
2016/07/28
251
0
MySQL类型float double decimal的区别

float数值类型用于表示单精度浮点数值,而double数值类型用于表示双精度浮点数值, float和double都是浮点型,而decimal是定点型; MySQL 浮点型和定点型可以用类型名称后加(M,D)来表示, ...

韩立伟
2017/06/30
0
0
java中浮点型数据的大小比较问题

一. 精度 举例:double result = 1.0 - 0.9; 这个结果不用说了吧,都知道了,0.09999999999999998 float和double类型主要是为了科学计算和工程计算而设计的。他们执行二进制浮点运算,这是为...

wangtx
2016/12/28
61
0
金融系统中正确的金额计算及存储方式

image 昨天微信群里在讨论金额计算及存储的话题,今天特来结贴一下。 经典的精度丢失问题 Java中的类型float、double用来做计算会有精度丢失问题,下面来看下面的示例。 上面的程序输出结果是...

架构之路
2017/12/01
0
0
能买几颗糖??

最近这几天吃“瓜”有点多,这次我们换点糖吃。 壹 Q:假设你有1块钱,而糖果五毛钱一颗,你买了一个,还剩多少钱? A:必须剩五毛。(我们都是幼儿园毕业了的人) 程序实现: 1.png 貳 Q:又...

梦想修补师
2018/01/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

2019 年最好的 7 款虚拟私人网络服务

糟糕的数据安全会带来极大的代价,特别是对企业而言。它会大致大规模的破坏并影响你的品牌声誉。尽管有些企业可以艰难地收拾残局,但仍有一些企业无法从事故中完全恢复。不过现在,你很幸运地...

linuxCool
22分钟前
1
0
OSChina 周一乱弹 —— 加油,还有11个小时就下班了

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @_全村的希望 :吴亦凡把大碗面正儿八经做成单曲了,你别说,还挺好听 《大碗宽面》- 吴亦凡 手机党少年们想听歌,请使劲儿戳(这里) @tom_t...

小小编辑
43分钟前
147
8
C++ vector和list的区别

1.vector数据结构 vector和数组类似,拥有一段连续的内存空间,并且起始地址不变。 因此能高效的进行随机存取,时间复杂度为o(1); 但因为内存空间是连续的,所以在进行插入和删除操作时,会造...

shzwork
今天
7
0
Spring之invokeBeanFactoryPostProcessors详解

Spring的refresh的invokeBeanFactoryPostProcessors,就是调用所有注册的、原始的BeanFactoryPostProcessor。 相关源码 public static void invokeBeanFactoryPostProcessors(Configu......

cregu
昨天
6
0
ibmcom/db2express-c_docker官方使用文档

(DEPRECIATED) Please check DB2 Developer-C Edition for the replacement. What is IBM DB2 Express-C ? ``IBM DB2 Express-C``` is the no-charge community edition of DB2 server, a si......

BG2KNT
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部