知识点回顾:
1. 比特位和字节
CPU 能读懂的最小单位(只能存放 0 和 1)—— 比特位,bit,b
内存机构的最小寻址单位 —— 字节,Byte,B
关系:1Byte == 8bit
因此,一个字节可以表示最大的数是:11111111
2. 二进制、十进制和十六进制
【扩展阅读】进制转换
3. 符号位
存放 signed 类型的存储单元中,左边第一位表示符号位。如果该位为 0,表示该整数是一个正数;如果该位为 1,表示该整数是一个负数。
一个 32 位的整型变量,除去左边第一位符号位,剩下表示值的只有 31 个比特位。
4. 补码
计算机是用补码的形式来存放整数的值。
正数的补码是该数的二进制形式。
负数的补码需要通过以下几步获得:
1. 先取得该数的绝对值的二进制形式
2. 再将第1步的值按位取反
3. 最后将第2步的值加1
5. 二进制表示最大值和最小值
6. 基本数据类型的取值范围
关于浮点数的存放形式和取值范围就没那么好理解了,对于初学者来说可以说是生涩难懂……
所以我们这里就不要求掌握了,不过我知道有些鱼油是拦也拦不住,所以我这里准备了两篇图文并茂的扩展阅读,有兴趣的朋友可以自己学习提升一下:
【扩展阅读】定点数:用二进制表示小数(#)
【扩展阅读】浮点数:表示更大范围的小数(#)
7. 彩蛋
最近苹果的 1970 事件可是炒的风风火火啊,终于让小甲鱼赶上一回热乎的了
日前有消息称,把 iOS 设备日期设置为 1970 年 1 月 1 日,重启后就会变砖。很多好奇网友尝试后中招。
苹果也在官网正式承认这一问题,并表示即将发布一个系统更新,以防该问题在未来影响 iOS 设备。
小甲鱼劝大家不要轻易尝试,至少不要拿自己的机子开玩笑,因为已经有很多烈士身先士卒了……
额,都说不要拿自己的机子开玩笑咯,但没让你停止探究的精神丫(还真有点心疼客服妹子了 )
不过也有朋友利用这次事件成功地换了新机,佩服
这究竟是咋回事呢?
这个 bug 最初的源头是在 reddit(类似国内的知乎),一个叫 vista980622 的网友发了一个帖子:
大致说了一下自己无意间发现了这个 bug,变砖。最后是以拆机的方式解决的。并且指出,黑客可以建立一个公共的 WIFI,在连上后,利用这个漏洞让他人的手机变砖。
然后,讨论区下面一位貌似苹果天才吧的工作人员在昨天给出了一个解决方案:
“Can confirm the solution. Our Genius team worked through a few steps and came to the conclusion that disconnecting the battery and reconnecting fixes the issue and allows the phone to boot to the lock screen.
At least we know how to fix it now and avoid those phone swap outs.
We've passed this info on globally to the relevant Apple Support teams.
It should be common knowledge to all stores worldwide by tomorrow.”
“可以确认这个解决方案。我们天才吧的团队试了几下,发现卸掉电池,再连接上,就能恢复手机。
至少我们现在知道如何解决这个问题,以及避免它发生了。
我们已经把这个消息传递给了全球的苹果售后支持团队。
明天全世界的Apple Store都会知道这个“常识性”的解决方案。”
没错,通过拆电池,让电池静置 10 分钟再装回去,系统会在开机时自动重设时间,从而让机子恢复正常。
但是这么蛋疼的 bug,究竟是怎么来的呢?
这要从 Unix 系统说起……
苹果 iOS 系统是来源于 Unix 系统,自然就继承了 Unix 使用时间戳(Unix epoch)表示系统时间的规定。
Unix 时间戳使用有符号整型来存储,规定按 UTC 时区的 1970 年 1 月 1 日 00:00 这个时间开始计时,即在此时间后每经过 1 秒,时间戳 +1。
这样一来,2016 年 2 月 16 日 17:00 就能够表示为 1455613200 秒,换算成二进制就是“……(64 位,前面还有 33 个 0)1010110110000101110010100010000”。
iOS 中时间的设定最多也只能回溯到 1970 年 1 月 1 日 00:00 也是这个原因,因为对于 iOS 来说,1970 年这一天,就是时间的起点。
那终点呢?
· 对于32位的苹果系统来说,是 2038 年 1 月 19 日 3:14:07;
· 对于64位的苹果系统来说,是 292,277,026,596 年 12 月 4 日15:30:08(约 2900 亿年后的事儿了)。
说了这么多,那导致这个 bug 的原因是什么?
虽然苹果在设置项目中限定了日期不能设置在时间戳零点之前,但可能局部关键功能具有查询过往信息的规则,并且在开机时自动触发。
当局部时间设置比时间戳的起点更早之后,终极问题出现了:我们应该怎么表示比时间戳起点更早的时间?
No pic you say a J8,直接上图(这是 32 位的情况,大家仔细观察数字的变化):
同样的道理,对于 64 位系统来说,起始时间之前的“负值”就相当于一个无穷大的时间值(也就动辄一两千亿年以后……)。
对于局部关键功能的时间值是无穷大,而系统的时间却是零点,打起架来的结果就是整个系统直接罢工(具体是哪部分功能罢工我们暂不得知,但是肯定是来自于像电池检查、系统内部的关键性功能。
这就是 1970 bug 的根本原因……




