当前位置:  技术问答>java相关

关于数字相加的问题(100.11f+200.22f=300.33002)?

    来源: 互联网  发布时间:2017-03-13

    本文导语:  public class test { public static void main(String args[]) { float a = 100.11f; float b = 200.22f; float c = a + b; System.out.println("a = "+a); System.out.println("b = "+b); System.out.println("c = "+c); } } 请问为什么结果是300.33002而...

public class test {
public static void main(String args[]) {
float a = 100.11f;
float b = 200.22f;
float c = a + b;
System.out.println("a = "+a);
System.out.println("b = "+b);
System.out.println("c = "+c);
}
}
请问为什么结果是300.33002而不是300.33?

|
public class testfloat {
public static void main(String args[]) {
float a = 100.11f;
float b = 200.22f;
float c = a + b;
double d=(double)a+(double)b;
double e=a+b;
System.out.println("float a = 100.11f;");
System.out.println("float b = 200.22f;");
System.out.println("float c = a + b;");
System.out.println("double d=(double)a+(double)b;");
System.out.println("double e=a+b;");
System.out.println("a= "+a+" b= "+b+" c= "+c);
System.out.println(" d="+d);
System.out.println(" float d="+(float)d);
System.out.println(" e="+e);
System.out.println("");

double a2= 100.11f;
double b2= 200.22f;
double c2=a2+b2;
System.out.println("double a2= 100.11f;");
System.out.println("double b2= 200.22f;");
System.out.println("double c2=a2+b2;");
System.out.println("a2= "+a2+" b2= "+b2+" c2= "+c2+" float c2 = "+(float)c2);
System.out.println("");

double a3=100.11;
double b3=200.22;
double c3=a3+b3;
System.out.println("double a3=100.11;");
System.out.println("double b3=200.22;");
System.out.println("double c3=a3+b3;");
System.out.println("a3="+a3+" b3="+b3+" c3= "+c3);
System.out.println("");
}
}
执行这个就知道了 float运算时为了精度要求总是先转换为double 再做运算

|
本身小数就不全是能用二进制精确表达的 只有2的负x幂才有可能精确表达,再加上精度的限制
double的精度很高的  三个double做这个运算时没有问题
可以看出
c2  和 d  一样
结果如下:
float a = 100.11f;
float b = 200.22f;
float c = a + b;
double d=(double)a+(double)b;
double e=a+b;
a= 100.11 b= 200.22 c= 300.33002
 d=300.3300018310547
 float d=300.33002
 e=300.33001708984375
double a2= 100.11f;
double b2= 200.22f;
double c2=a2+b2;
a2= 100.11000061035156 b2= 200.22000122070312 c2= 300.3300018310547 float c2 = 300.33002
double a3=100.11;
double b3=200.22;
double c3=a3+b3;
a3=100.11 b3=200.22 c3= 300.33
不过只能说明原因可能时这样  只是充分条件吧  
我很穷

|
我的理解是,这个可能和c里面的原理是一样的。
因为在对于精度数字的存储/取出的过程中,实际上在内存中,数字并不是非常精确的,例如你定义了100.11,可能在内存中,实际值是100.1100000001,而对于每一次的读可能这个值都会又一些的变化,这也就是为什么在c中比较两个float或者double型的数字是否相等不使用纯粹的==来比较,而是诸如(a-b>1E-6)等来表示的。这是我的理解,仅供参考,谢谢。

|
在java中定义数据类型是,对于float的使用一般是不怎么赞成的,除非在表示精度要求不高,而存储空间紧张的情况下才用,所以一般我们就是用double。如果在赋值时,没有加上后缀f,数字就默认为double,所以,可能时在a+b以后,由于没有f后缀,系统将a+b的值作为double对待,然后在转化成float,你可以试试,如果将c声明为double,输出的时候你就可以发现c又很多的位数,如a=100.11;b=200.22 ;c=300.33001708984375,到第一个四舍五入的位置舍去进位就输出了(在c为float的情况下),以此类推,你可以再试试

|
呵呵,确实比较难理解,可能是这样:在计算的时候为了保证数据的准确性,无论是否是double型的一律转化成double型进行运算,结果在转float,由于float的有效小数位数是6到7为,所以就四舍五入了,我只能这么理解了

|
原因就是浮点数可以精确表示大于一的数和小数部分为1/2^n之和的数(例如0.5,0.125),所以会出现问题

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • linux c/c++ IP字符串转换成可比较大小的数字
  • 数字签名,数字签名,数字签名!!
  • java实现判断字符串是否全是数字的四种方法代码举例
  • asp正则表达式匹配数字$数字$数字$
  • 高手请赐招:数字签名与数字认证的区别,尤其是概念上的区别。谢谢!
  • 请问linux用户名能否用数字?怎么才能用数字开头呢?
  • 请教:Java 中数字字符串转化为数字的问题
  • awk的数字运算中,数字变量的值的范围多少?
  • jquery禁止输入数字以外的字符的示例(纯数字验证码)
  • 对applet坐数字签名后,如果重新用jar对applet打包,需要重新做applet数字签名吗?
  • 请问,用c如何将一串数字字符转换成数字
  • 只能是字母或数字或者是字母和数字的组合的正则previousSibling
  • 请问Java中如何在控制台一行内输入n个数字,然后再在一行内输出这些数字
  • sql server 字段 全角数字转半角数字的代码分享
  • c语言中怎样从字母和数字组成的字符串中提取数字?
  • 如何让IE认识applet所带的数字签名,而不是让证书仓库认识这个带数字签名的applet,就是说不装jdk也可以在IE里面使用带有签名的applet,详情请进
  • php生成随机字符串(自定义纯数字、纯字母或数字字母混合)
  • 关于数字签名的几点疑问??另:csdn的数字签名帖子我都看过,不要介绍给我,我是诚心提问!!
  • python实现猜数字游戏(无重复数字)示例分享
  • awk的数字计算,能指为long long 64位整数么?
  • c#判断输入内容是否数字的代码


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3