回覆列表
  • 1 # 使用者7371823184645

    這是一個歷史遺留問題,屬於語法糖,叫做百分計算器。

    按人類語義的理解,你去買東西,100元錢減去10%,那就是90元。早期的計算器就可以直接這樣寫100-10%。再比如,一隻股票股價10,增長了50%,可以直接寫10+50%。這麼設計更深層次的原因可能與早期計算器的按鍵數量有限,以及單步運算的性質有關。具體有答主已經作了回答。

    手機計算器保留了這種特性。

    所以10%+10%就是0.11

    下面有具體說明。

    How does the calculator percent key work? | The Old New Thing

    我經過初步探索,發現該運算的優先順序比較特殊,需要的條件為:

    exp1 [+-] exp2 % [+-] exp3 = exp1*(1 [+-] exp2 %)[+-] exp3

    exp1 的值會被優先計算,比如 5+5-10%=9如exp2與exp3之間為 [ * / ],則會將exp2 % [* /] exp3 作為整體計算,比如5+10%*10=6

    更新下,部分國內計算器結果是0.2,是因為國內手機廠商自己做了修改,符合華人打幾折的說法。上述的10% off其實是外華人的邏輯。魅族的工程師已經在微博說了他們在國內使用了0.2的方案,在國外使用0.11的方案。

    部分網友仍然認為這是BUG,而不是feature。我找了一份Github上計算器的原始碼。和大多數計算器的處理方法一致,先將表示式轉化為字尾表示式,再從左到右掃描一次就可以得出答案。

    hoijui/arity

    我已去除和百分運算無關的部分。

    對該程式碼運算過程舉個例子:

    表示式:a+b%+c表示成字尾表示式ab%+c+Code佇列:[ a , b, % , + , c , +]有個s棧,開始為空:[]每次遇到常數,p自增1,再在s中p指向的位置放入該常數。每次遇到+-,p會自減1。從左向右開始掃描code,pc為指標。首先遇到常數a,b,放入s中:[a,b] ,p指向b繼續掃描,遇到%,將p指向的內容*0.01,s變成:[a , b*0.01];同時,percentPC指向code中的%。繼續掃描,遇到+,pc此時指向的位置為percentPC+1,由三元判斷式,a=a+a*b*0.01,p重新指向a,s變為[a+a*b*0.01,b*0.01]繼續掃描,c替代b*0.01繼續掃描,遇到+,此時的pc不等於percentPC+1,s[p]=s[0]=a+a*b*0.01+c結束掃描,返回指標p,s[p]就代表結果,完結。

    可以明顯看出,加減法中多了一步判斷:

    本質就是檢視字尾表示式+-之前的符號是否為%來執行該+-的操作。

    如果不需要該特性,只需將這一句改為:

    另外有網友提出括號的問題,部分計算器的字尾表示式生成時,遇到左括號“(”會將其作為一個標記插入佇列。於是,a+(b%)字尾表示式會變成 a b % mark +,加號之前的符號不再是%,不再執行特殊百分比加法。也有計算器加了括號也沒有用,這也很好推斷,該計算器在生成字尾表示式時沒有對括號作插入標記。

    計算器的處理過程就是這麼簡單粗暴,也不涉及什麼高深的演算法。對於百分運算的特殊處理也只需多一個指標就能做到。所以你能想到了,要適應國內的習慣,只需要加一個地區判斷替換語句就可以了。

  • 中秋節和大豐收的關聯?
  • 吳秀波出了這事兒,你們還去看他電影嗎?《情聖2》票房會受影響嗎?