在写博客这方面我是个新手,表达能力的改进空间还有很大。上文简单的回答了朋友的问题,但貌似有点“以其昏昏,使人昭昭”的感觉。朋友继而追问,又log又方程的,你如何还可以心算呢?
其实,计算这类问题,只要记住两个数就可以了,一个是0.3,一个是3.3。一亿个查询单位用binary search要用多少次查询的问题,便是用8*3.3 = 26.4(8/0.3=26.7)计算出来的。这个乘法运算,心算不成问题吧?
这两个数又是从何而来的呢?0.3其实是log2=0.301……的约数,而3.3就是1/0.3 = 3.33……的约数,大家参考一下上文的方程式,便会知道为何可以这样子计算了。
此外,8是来自10^8,即一亿这个数字中0的个数。这便是binary search神奇之处了,想想,如果数组有十亿个数据,8便变为9,然后9*3.3=30.7亦即31次查询就可以了。聪明的你可能已发现,其实数组元素个数每增加十倍,查询次数就增加3.3次而已。
对这话题的进一步思考,使我想到,其实这个方法也可以用在估算二进制数字的数值上。例如,一个unsigned 32 bit整数最大值为2^32-1,忽略掉后面的1,将32*0.3就可以估算出2^32大概的数值介乎10^9至10^10之间,亦即10亿与100亿之间。这样的估算虽不能精确算出答案,但却能大概知道数值的数量级别。
你也许会说,这样的估算有什么利用价值呢?如果你有这种疑惑,坦白告诉你,我也曾经有过。在我之前的工作中,我的主管经常叮嘱我要锻炼对数字的感觉。老实说,我对他的忠告,很长一段时间以来都是置若罔闻的。心想,现在都什么时代了,要计算条算术题,敲几下键盘或者按几下按钮不就成了吗?直到后来有一段时间,我们经常在一起开会,发现他总能一眼就看出我的程序中的bug,我才明白并惊讶于这类估算方法的重要性。它其实就是能使我们快人一步,甚至是能人所不能地看出问题的所在。后来,他更教导我,从事财经相关的工作,必须要负责,绝不能计算出结果就当做完事。严格的测试程序当然要做充分,但还要经常警觉,常常估算数字是否合理,因为很多错误,其实都是相差数量级的,比如,数字后面多了个0,又或者把人民币算成了美金等……只要“心中有数”,这些问题就不会看不到的。他还教导说,除了在输出上可以运用估算方法,很多其他地方其实也都可以用到,比如程序的响应时间及其内存占用大小是否合理等……每次想起他的谆谆告诫,我都感觉受益匪浅,但又不知何时才可以锻炼出他这样的敏锐眼光,看来除了努力实践也没其他捷径了!