今天,陈老师和老王讨论一个问题,记下来和大家分享一下,有需要的同学,可以一起复习一下。
1,首先是程序的调试观念。这个是重要的,学习任何一门语言,语法只能服从,老王建议熟能生巧,不要记忆或者背,因为这个东西很多时候是不可靠的,尤其是刚开始接触多门语言的时候,会出现很不适应的情况。因此,搞不清楚的时候,直接代码show结果,比任何书都有用!(这也是老王之前表达的很多书不合格的原因,有时候相互矛盾,学生无所适从)。学计算机的孩子们,要学习硅谷的叛逆精神,不要尽信书(此处经典大神级教材在学习初期还是要信的,之后你有了质疑的能力,也许就发现了好问题),发现书中的错误,是老王年轻时候的一个乐趣,现在也会,但琐事原因导致读书少了很多,惭愧。
2,不多说理论,需要的搜索即可。
关于float和double的有效数字问题,老王本以为没啥问题了,感谢陈老师的求实精神,老王受教了。所谓float的8位,double的16位(也有7位和15位的说法),大家不必强记,代码走一遍就了解了。
class Noname1
{
public static void main(String[] args)
{
float f1=12.1234561f;//9位
float f2=12.1234565f;//最后一位为了检验四舍五入用
float f3=12.1234570f;//最后一位写成0,不会显示出来
double d1=123456.12345678902;//17位
double d2=123456.12345678906;//最后一位为了检验四舍五入用
double d3=123456.12345678909;//最后一位为了检验四舍五入用
double d4=123456.12345678910;//最后一位写成0,不会显示出来
System.out.println("f1="+f1);
System.out.println("f2="+f2);
System.out.println("f3="+f3);
System.out.println("zhuan="+(float)d1);//测试double转float
System.out.println("d1="+d1);
System.out.println("d2="+d2);
System.out.println("d3="+d3);
System.out.println("d4="+d4);
}
}
3,结果简要分析
(1)float输出,前7位有效数字是真实值,第8位是估算值,可能和原始一致,可能是四舍五入上来的。这个结果和数学一致。因此可以得出,java下float8位有效数字的结论。
(2)double转float为什么是9位输出?矛盾吗?从代码可以看出,前8位有效数字是没问题的,第9位的输出和原数字没啥关系,也不符合四舍五入,因此不必过于担心,8位有效数字依然成立,至于显示出第9位的值,不能保证其准确性。
(3)double值,前15位有效数字是真实值,第16位是估算值,可能和原始一致,可能是四舍五入上来的(如d3,但d2不行,这个结果和数学貌似不一致。在下一点说明原因。)先得出结论,java下double16位有效数字的结论。
至于此处显示的第17位,仅仅是因为其在理论范围内的值。为了进一步测试,换了几个数值。如下图(没错!086正常显示17位,087就进位了16位。这个是有效数字玩我吗?是传说中的系统问题吗?有兴趣的看下一点即可)
(4)float显示8位还是9位?double显示16位还是17位?
经过理论部分的学习(此部分资料较多,可以自行搜索),float有效指数为23位二进制,double为53位二进制。
float部分:
12.1234565二进制1100.000111111001101011011000010111011111101010000111
取23位:1100.0001111110011010110(11000010111011111101010000111)
进位取1100.0001111110011010111
十进制:12.123456954956055(取12.123457)
double转float:
123456.12345678902二进制
11110001001000000.000111111001101011011101001101110101
取23位:11110001001000000.000111(111001101011011101001101110101)
进位取11110001001000000.001000
转十进制123456.125
double显示(主要解释086不进位,087进位即可)
123456.123456789086
二进制:11110001001000000.000111111001101011011101001101111001
取53位:17+36位,整好53位
所以保留后转十进制,还是123456.12345678908(显示17位)
附上转换工具
123456.123456789087
二进制:11110001001000000.00011111100110101101110100110111101
取53位:17+35位=52,缺1位,在后面补1个0
转十进制:123456.1234567891
综上,不是系统原因,二进制位可以解释。计算机的同学们建议把理论和实践联系一下,最基础的问题,能够挖一挖,可能会理解很多事情。
因此,有效数字应该是以二进制为准,从数学上看,float的有效数字(8-9位显示)double的有效数字(16-17位显示)。
望大牛路过时斧正错漏。