众力资讯网

谁说电脑不会算错?它早就错过不止一次了,只是没告诉你 电脑算错账的方式其实比你

谁说电脑不会算错?它早就错过不止一次了,只是没告诉你

电脑算错账的方式其实比你预想的多得多,只不过大部分时候你没察觉。更离谱的是,有些错错得还挺有创意。

比如说,被外太空的一颗粒子打了一下。

宇宙里的高能粒子击中内存某个位置的时候,会直接翻转那个比特位——0变1,1变0,也就是所谓的位翻转。这件事不是理论推演,是有实战记录的。

2003年比利时一场选举,某位候选人莫名多出了4096张票,关键是那个投票站全部注册选民加起来都没这么多。因为4096刚好是2的12次方,一番漂亮的回溯推理之后,矛头指向了"宇宙射线打内存"。这不是孤证。2013年,有人直播玩一款经典平台跳跃游戏,角色突然凭空瞬移了。另一位硬核玩家在2015年悬赏一千美元求复现这个瞬间,把这桩奇案彻底拱出了圈。研究人员最终的判断也是:大概率一粒高能粒子打翻了角色的坐标数据。

两个案例隔了十来年,但千万别以为内存被击中的概率有多低。IBM在1996年就估过一笔账:当时256兆内存的台式机,平均每个月就会碰上这么一次。现在谁还用256兆?换算一下,大概每G内存每周就会吃到一次位翻转,一台16G内存的机器可能一天挨两回。所以有些脑子很活的科学家就提过一个观点:蓝屏死机,说不定也是粒子惹的祸。

好在这些年技术往前走了,内存容量虽然放大了,单个存储单元的物理尺寸反而缩得更小,被命中的概率没以前那么离谱了。而且现在的服务器和中高端机器基本都配了纠错内存,可以在硬件层面自动发现并修正单比特翻转。但不管怎么防,物理层面的翻转仍然是事实。所以忍不住想问一句:银行卡余额老是那么少,是不是也被打过?

再说一个纯硬件层面的经典翻车。1994年,奔腾处理器的一批芯片藏着一个根子上的缺陷。发现它的不是工程师,是一位数论教授。Intel的硬件查找表里漏了五个数据,导致处理器在除以某些特定数值时,会产出极微小的精度偏移。最后的结果是,1995年Intel掏了四亿多美元的赔偿金。如果你手头还有那个年代的老片子,算一下那组特定的算式,正常归零,你却可能得到256。

还有一个惨烈得多。人类习惯十进制,在人的眼里0.1是个简单的、整整齐齐的数。但落到二进制的机器里,0.1是一个无限循环小数,二进制表达的0.1是一长串0.00011001100110011……永远写不完。

1991年沙特的达兰基地,爱国者导弹防御系统内部用一个24位的寄存器来存时间,以十分之一秒为单位计数。因为寄存器长度就那么大,后面那串无限循环的尾巴被直接切掉,每一次计时都产生大约0.000000095秒的误差。那套系统连续开机运转了一百个小时没重启,误差一点一点往上摞,最后系统时间跟真实时间差了0.34秒。来袭的那颗飞毛腿末端速度每秒超过一千六百米,0.34秒就是五百多米的跟踪偏差。系统误判为不需要拦截,没发射,营房被命中,二十八名士兵没回来。

所以你看,错一次就是一次大的。

这还都没说到计算机从底层架构上就刻着的那种限制。比如让它去算π这种永远写不完的、没有循环节的小数。算到几百万位、几百亿位的时候,最大的瓶颈反而是硬件本身。一个单精度浮点数只有三十二个比特的存储空间,哪怕用到六十四位的双精度,也顶多撑到十五到十七位十进制的精度。π随便甩一截出来就把它撑死了。

解法是把数字当成一串字符串、一个长长的数组来对待,数组的一号格装第一位数字,二号格装第二位,依次排下去。想算到一百亿位,就开一块能塞进一百亿个数字的庞大数据。但这样一来,计算机就只能像小学生列竖式一样去做乘法。普通算法里,第一位的每一位都要去乘第二位的每一位,计算量是位数的平方级别。如果位数N是一百亿,那就是一百亿乘一百亿,十的二十次方次操作。即使扔给超算,光做这一回乘法就要几百年,而算π的这条路需要无数次这种规模的大数乘法。

最后只能搬出专门为计算机量身打造的高精度大数算法,用二十世纪最杰出的数学成果之一——快速傅里叶变换,把乘法转成信号处理。

总而言之,"电脑永远算不错"是一种幻觉。它只是大多数时候错得不够显眼,或者错的时候你恰好没抬头看罢了。