本文链接:
https://mp.weixin.qq.com/s/MnZFWk_yYN67jSq7fruhHg
争议话题
近日, 一则热搜 #手机计算器全线阵亡# 的话题在网上火了起来. 不少网友惊奇地发现, 在自己的智能手机上打开计算器, 计算 10% 10%, 得出的结果竟然是 0.11!
网友反映, 华为, 苹果, OPPO,VIVO, 小米, 一加等多个品牌的手机计算器都出现了这样的 "BUG"; 也有人发现, 魅族, 锤子科技, 努比亚手机的计算器结果是 0.2, 贴上了很多逻辑思维, 文化差异的标签, 下面用两个手机对比一下差异.
为什么会出现这样的 "BUG"?
不少科技博主指出, 出现这样的 "BUG", 原因主要是计算器对输入符号的理解不同. 一些手机厂商的高管也出来进行了解释, 比如魅族科技的副总裁华海良在微博的发言:
还有荣耀业务部总裁赵明, 也在微博发表了自己的观点, 很有意思.
没想到在 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,"%" 在不同的场景之下有不一样的作用, 人们也在不断更新进步, 将这些生活场景应用在机器软件上, 智能的路还有很远, 但就在未来.
讨论一下吧
你的手机在不同模式下是什么样的呢?
这种计算方式有必要吗?
身为一名程序员, 这个锅你愿意背吗?
来源: http://www.bubuko.com/infodetail-3203137.html