版權聲明:本文爲博主原創文章,遵循 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等原創技術文章。後臺免費獲取經典電子書籍和視頻資源,實時更新,原創不易,請多支持,謝謝!