版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接和本声明。html
本文连接:http://www.javashuo.com/article/p-wkksefyp-ev.htmlgit
https://mp.weixin.qq.com/s/MnZFWk_yYN67jSq7fruhHg程序员
争议话题github
近日,一则热搜#手机计算器全线阵亡#的话题在网上火了起来。很多网友惊奇地发现,在本身的智能手机上打开计算器,计算10%+10%,得出的结果居然是0.11!算法
网友反映,华为、苹果、OPPO、VIVO、小米、一加等多个品牌的手机计算器都出现了这样的“BUG”;也有人发现,魅族、锤子科技、努比亚手机的计算器结果是0.2,贴上了不少逻辑思惟,文化差别的标签,下面用两个手机对比一下差别。编程
为何会出现这样的“BUG”?windows
很多科技博主指出,出现这样的“BUG”,缘由主要是计算器对输入符号的理解不一样。一些手机厂商的高管也出来进行了解释,好比魅族科技的副总裁华海良在微博的发言:ide
还有荣耀业务部总裁赵明,也在微博发表了本身的观点,颇有意思。函数
没想到在18年的时候,MIUI就回复了这个问题,如今才火起来,估计当时都是懵懵的,不明觉厉。学习
官方解释
咱们在进行四则运算时,都是先乘除后加减,若是有括号就先算括号里的。而百分号“%”则表明“除以100”,和乘除是一样的优先级。所以,咱们计算10%+10%得出的结果为0.2。即10%+10%=0.1+0.1=0.2。
在传统的百分号运算中,计算器对输入符号的理解和咱们是不同的。传统的百分号运算都是在第一个数的基础上增长10%做为第二个数。也就是X+n%就是在X的基础上上浮n%,也就是X+X*n%。在10%+10%的运算中,计算过程即为10%+10%=10%+10%*10%=10%*(1+10%)=0.11。
从程序员角度来看代码
做为一个程序员,天然要从代码的角度来看了。Windows Calculator应用程序是一个用 C ++编写的现代Windows应用程序,预装了Windows。该应用程序提供标准,科学和程序员计算器功能,以及各类度量单位和货币之间的一组转换器,其中只有标准模式有“%”。
为此我在github上找到了微软开源的计算器项目,我找到关于“%”计算的部分,摘出了其中相关的代码:
case IDC_PERCENT: { // If the operator is multiply/divide, we evaluate this as "X [op] (Y%)" // Otherwise, we evaluate it as "X [op] (X * Y%)" if (m_nOpCode == IDC_MUL || m_nOpCode == IDC_DIV) { result = rat / 100; } else { result = rat * (m_lastVal / 100); } break; }
注释中也已经解释了,当操做符是乘法或者除法的时候,与“%”相关的直接除以100再和另外的数操做(即咱们一般认识的算法),不然就按照上一次结果的百分比来计算。
因此,若是你计算10%+10%,它是下面的过程:
结果 —— 操做
0 初始值0 输入10%,计算0 + 10% * 00 输入+10%,计算0 + 10 *0
最终会获得0
只不过不少手机计算器中直接把第一个10%当成了0.1,这也就是咱们看到一些手机计算器最终会获得0.11结果的缘由
可是若是你计算1000 * 10%,它按照原始的方式计算,即计算获得100。因此这是有意为之,而并不是什么bug!程序员表示不背这个锅。
另外咱们都知道,“%”经常使用于取模运算,它是一个二元运算符,这也正是科学模式和程序员模式没有“%”的缘由,由于“Mod”取代了,例如:7%2 = 1
因此当你在Linux的命令行输入bc,而后输入10+10%,你会看到下面的结果:
$ bc 10+10% (standard_in) 3: syntax error 7%2 1
没错,它会提示你语法错误,而不是帮你计算10的10%,由于这里的“%”并不是计算百分数,而是用来取模的。因此在windows自带的程序员计算器和科学计算器中,有“Mod”,而没有“%”。
注意:Linux下,bc命令是一种支持任意精度的交互执行的计算器语言,能够很方便的进行浮点运算,固然整数运算也再也不话下。
另类解决办法
若是在输入时,将每一个10%乘1,就能获得正确答案,至于为何会这样,就交给你们去思考吧。
总结
从程序员视角看,这不是Bug,“%”在不一样的场景之下有不同的做用,人们也在不断更新进步,将这些生活场景应用在机器软件上,智能的路还有很远,但就在将来。
讨论一下吧
你的手机在不一样模式下是什么样的呢?
这种计算方式有必要吗?
身为一名程序员,这个锅你愿意背吗?
推荐阅读
(点击标题可跳转阅读)
关注公众号【技术让梦想更伟大】,获取更多Linux/C/C++/Python/FPGA等原创技术文章。后台免费获取经典电子书籍和视频资源,实时更新,原创不易,请多支持,谢谢!