java float 精度缺失问题?
inta=0x7fffffff;intb=0x7ffffff0;System.out.println(a-b);//结果15floatfa=a;floatfb=b;Sys...
int a = 0x7fffffff;
int b = 0x7ffffff0;
System.out.println(a-b);//结果15
float fa = a;
float fb = b;
System.out.println(fa-fb);//结果0.0 ( 这里为什么会是 0.0 啊? )
double da = a;
double db = b;
System.out.println(da-db);//结果15.0 展开
int b = 0x7ffffff0;
System.out.println(a-b);//结果15
float fa = a;
float fb = b;
System.out.println(fa-fb);//结果0.0 ( 这里为什么会是 0.0 啊? )
double da = a;
double db = b;
System.out.println(da-db);//结果15.0 展开
展开全部
原因是浮点数用科学计数法来储存数的,只是跟我们初中学的十进制科学技术法不一样,它是二进制的科学计数法。
比方说:(二进制数用[b]结尾)
3=11[b]*2^0=1.1[b]*2^1,注意1.1[b]是二进制小数,不是十进制小数。
15=1111[b]=1.111[b]*2^3
那么我们来数一数int a有多少位有效数字:
7fffffff->7共三位,后面7个F,每个F4位,总共31位。
7ffffff0->总共27位。
那么浮点类型可以储存多少位有效数字呢?
float:符号位1位,指数位8位,有效数字位23位
double:符号位1位,指数位11位,有效数位52位。
那答案出来了:
float才23位有效数位,最多支持24位有效数字。那么int a后面还有7位,int b后面还有3位。那怎么办?精度不够就“四舍五入”呗!(好吧,其实是0舍1入)
那么在float类型那里,两个数都会被“0舍1入”为8000 0000,结果就是一相减为0。
而double类型支持53位有效数字,绰绰有余。
你可以试着printf一下float fa,fb,看是否都为8000 0000h
比方说:(二进制数用[b]结尾)
3=11[b]*2^0=1.1[b]*2^1,注意1.1[b]是二进制小数,不是十进制小数。
15=1111[b]=1.111[b]*2^3
那么我们来数一数int a有多少位有效数字:
7fffffff->7共三位,后面7个F,每个F4位,总共31位。
7ffffff0->总共27位。
那么浮点类型可以储存多少位有效数字呢?
float:符号位1位,指数位8位,有效数字位23位
double:符号位1位,指数位11位,有效数位52位。
那答案出来了:
float才23位有效数位,最多支持24位有效数字。那么int a后面还有7位,int b后面还有3位。那怎么办?精度不够就“四舍五入”呗!(好吧,其实是0舍1入)
那么在float类型那里,两个数都会被“0舍1入”为8000 0000,结果就是一相减为0。
而double类型支持53位有效数字,绰绰有余。
你可以试着printf一下float fa,fb,看是否都为8000 0000h
展开全部
int a = 0x7fffffff;
int b = 0x7ffffff0;
System.out.println("a:"+a+" b:"+b);
System.out.println(a - b);// 结果15
System.out.println("*****************************");
float fa = a;
float fb = b;
System.out.println("fa:"+fa+" fb:"+fb);
System.out.println(fa - fb);// 结果0.0 ( 这里为什么会是 0.0 啊? )
System.out.println("*****************************");
double da = a;
double db = b;
System.out.println("da:"+da+" db:"+db);
System.out.println(da - db);// 结果15.0
System.out.println(Float.MAX_VALUE);
System.out.println(Float.MIN_VALUE);
float一共是32位,第一位是符号位,2-9位共8位表示整数位,2的8-1次方等于128,后面23位是表示小数的。关键就是后面的23位,因为a,b比较大,所以采用科学计数的方式,根据实验结果好像是统一往前进了一位,蛮诧异的。
补充一句:现在用double比较多,因为计算机设计的原因,double运算速度比float快
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2013-09-03
展开全部
System.out.println(fa+"-"+fb+"="+(fa-fb));
2.14748365E9-2.14748365E9=0.0
不是精度,而是转换出的问题。
用大数来计算,就可以
java.math.BigDecimal ba=new java.math.BigDecimal(a);
java.math.BigDecimal bb=new java.math.BigDecimal(b);
System.out.println(ba.toPlainString()+"-"+bb.toPlainString()+"="+(ba.subtract(bb)).toPlainString() );
2.14748365E9-2.14748365E9=0.0
不是精度,而是转换出的问题。
用大数来计算,就可以
java.math.BigDecimal ba=new java.math.BigDecimal(a);
java.math.BigDecimal bb=new java.math.BigDecimal(b);
System.out.println(ba.toPlainString()+"-"+bb.toPlainString()+"="+(ba.subtract(bb)).toPlainString() );
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询