当前位置: 技术问答>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 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 再做运算
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
不过只能说明原因可能时这样 只是充分条件吧
我很穷
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)等来表示的。这是我的理解,仅供参考,谢谢。
因为在对于精度数字的存储/取出的过程中,实际上在内存中,数字并不是非常精确的,例如你定义了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.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。