你不知道的计算机的世界

前言

昨晚的一堂课确实有些颠覆了认知,因为感觉到虽然自己从事java多年,却未曾理解计算机的世界。你是不是跟我一样,对计算机的世界的理解就是:不就是0和1吗?其实这太表面了。。

经典题目

题目一

float a = 0.5F - 0.25F;
float b = 0.25F- 0.0F;

Float c = Float.valueOf(a);
Float d = Float.valueOf(b);

System.out.println(a == b);
System.out.println(c.equals(d));

题目二

float a = 1.0F - 0.9F;
float b = 0.9F- 0.8F;

Float c = Float.valueOf(a);
Float d = Float.valueOf(b);

System.out.println(a == b);
System.out.println(c.equals(d));

答案

题目一是两个true,而题目二则是两个false。是不是有点懵?欢迎来到计算机的世界!

计算机是如何表示小数的

  1. 计算机只有0和1。这意味着所有我们习以为常的十进制的数,都要先转换为二进制,才能被计算机所理解。
  2. 小数在计算机中是以《科学记数法》来表示的。原因嘛,第一,小数位可能是无限的。例如圆周率。如果存储空间不限,理论上可以精确表示。然鹅,我们计算机的存储是有限的。其次,科学记数法本身就是用来表示极大数和极小数的,正好可以利用这一点。但是,我们都知道使用科学记数法都会涉及到有效位数的问题。如果一个数在有效位数内刚好能够完全表示,那么这个数就是准确无误的,而如果不能够完全表示,则面临着四舍五入的命运,即精度丢失!
  3. 上面这两条大家应该都认识,但是可能组合在一起,就理解不到位了。因为十进制中的小数,要先转换成二进制中的小数,然后再使用科学计数法才能够表示。而科学技术法的有效位数取决于我们使用的是Float还是Double.

计算机世界诡异的小数

由于存在进制转换,这使得有限的小数也可能变成无线小数。

  • 在十进制中的1/3,在三进制中就是0.1
  • 在十进制中的0.9,在二进制中竟然是个无线循环小数。
  • 在十进制中的0.5,在二进制中变成了0.1

在我理解看来,从物理学的角度去看,就是参考系发生了变化。这个神奇的地方,让我不禁猜想会不会我们所熟知的圆周率,在某个进制转换下,就是一个有限的正常的小数???也就瞎想一下哈,别当真。

回到题目

现在再回来看,能理解了吗?题目一中的小数,都可以被二进制完整的表示,而题目二中的小数却不能。小数0.9迫于存储空间的原因,被使用科学记数法截取了,因此精度丢失了。

  • 十进制到二进制的小数
  • 0.5(1/2) -> 0.1
  • 0.25(1/4) -> 0.01
  • 0.125(1/8) -> 0.001

总结

  1. 小数从十进制到二进制转换后,可能是个无限小数。
  2. 小数在计算机世界是用科学记数法表示的,可能存在精度丢失。
  3. 小数从十进制转换成二进制进入计算机的世界后,可能存在精度丢失。只有当分母可以被二进制整除才不会丢失精度。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值