--- title: Minecraft的計算規則與比較操作 tags: math, calculation --- # 一、數值計算操作(Arithmetic Operation) ## 1. 記分板計算(Scoreboard Arithmetic Operation) * 記分板僅能儲存整數(integer),且數值儲存範圍為 [-2147483648, 2147483647]=[-2^31^, 2^31^-1] * 支援以下計算操作(arithmetic operation): * `+=` : `a=a+b`,使a加上b的值 * `-=` : `a=a-b`,使a減去b的值 * `*=` : `a=a*b`,使a乘上b的值 * `/=` : `a=a/b`,使a除去b的值 * `%=` : `a=a%b`,使a模去b的值(a mod b),又或稱為 使a為a除b的餘值 * `= ` : `a = b`,使a為b的值 * `< ` : `a=min(a,b)`,使a為a和b的最小值 * `> ` : `a=max(a,b)`,使a為a和b的最大值 * `><` : `swap(a,b) `,交換a和b的值,<font color=red>唯一的雙向操作(bi-operation)</font> --- ## 2. 小數計算(Floating Number Arithmetic Operation) --- # 二、比較操作(Comparison Operation) * 數值區間(range)格式: `u` : 記作區間:`[u,u]`, `value==u`,若值等於u `..u ` : 記作區間:`(,u]`, `value<=u`,若值小於等於u `u.. ` : 記作區間:`[u,)`, `value>=u`,若值大於等於u `u..v` : 記作區間:`[u,v]`, `u<=value<=v`,若值大於等於u、小於等於v 以下我們會將數值區間的變數 v 記做`[r]` ## 1. 實體選擇器(selector) selector中有提供可以查詢scoreboard數值與區間的方式 `@#[score={obj=[r]}]` : 若目標的obj分數介於 r 數值區間中 ## 2. execute if score 相比於selector可以用來比較變數之間的情況,其額外提供了以下幾種比較方式: * `< ` : `a < b `,若a小於b * `<=` : `a <= b`,若a小於等於b * `= ` : `a == b`,若a等於b * `> ` : `a > b `,若a大於b * `>=` : `a >= b`,若a大於等於b * `matches [r]` : `a∈[r]`, 若值介於 r 數值區間中 > <font color=red>請注意</font>,在 [細談指令分析─記分板比較]() 中有提及到以下效率優化的規則: > 若比較的scoreboard數量只有1個時,使用execute if score會比用selector還要有效率, > 但若比較的scoreboard數量為2個以上時,請盡可能避免使用execute if score來比較 --- # 如何快速解析運算式的順序 有時候觀察一個數學式子,像是一個$\frac{4x(180-x)}{40500-x(180-x)}$之類的式子都要觀察老半天, 或是看到別人寫的計算數學的函數又不知道該怎麼樣快速看的話, 我們在這裡會提供一個可以快速解析的方式 在這裡要提及數學式結構的概念: | 表達式 expression | 格式 | 範例 | | -------- | -------- | -------- | | 前序 prefix | + a b | \* + 2 3 7 | | 中序 infix | a + b | ( 2 + 3 ) \* 7 | | 後序 postfix | a b + | 2 3 + 7 * | 中敘式是我們一般解數學題目時會使用的方式, 而轉成後序式可以讓電腦更方便計算,也不用考慮到括弧的問題 > 此概念之後在學習程式的「資料結構」部分時會再提及到一次 --- ### 轉換中序式 為 後序式(Infix Expression to Postfix Expression) 假設現有一式:$x-\cfrac{-b+\sqrt{b^2-4ac}}{2a}$ 首先步驟是將其攤平:$x-(\sqrt{b^2-4ac}-b)/2a$ 後續轉換的步驟是從左往右解析,而轉換後的後序式會是這樣: $x,b,b,*,4,a,*,c,*,-,√,b,-,2,a,*,/,-$ 我們可以將其依序解析: ![](https://raw.githubusercontent.com/xuese0513/images/654de28f17c8e1cdc1059886cd781aa1a980f4c9/article/Minecraft%E7%9A%84%E8%A8%88%E7%AE%97%E8%A6%8F%E5%89%87/postfix%20operation%20steps.svg) > 在這裡要特別注意根號(√)是一個單變數函式(一元運算),他只會用掉一個數 如果不是很知道該怎麼轉換的可以利用這個線上轉換器來輔助: [Data Structure : Infix Postfix Prefix - Converter & Evaluator](https://raj457036.github.io/Simple-Tools/prefixAndPostfixConvertor.html) --- ### 知道了後序式之後能做什麼? 當然就是直接寫出指令了,還能做甚麼? 如果還不是很了解的話,可以把「後序運算的轉換過程」看成是一個「計算流程」, 每當遇到一個運算符(Operator)時就會進行一次計算, 在這裡要如何節省變數用量就會變成一個很重要的一環了 用範例來看,已知的參數有`(x,a,b,c)`,在這裡我們會需要加開兩個變數`(k,p)`: ``` k = b k *= b // k == b^2 p = a p *= 4 // p == 4a p *= c // p == 4ac k -= p // k == b^2-4ac k = sqrt(k) // k == sqrt(b^2-4ac) k -= b // k == sqrt(b^2-4ac)-b p = a p *= 2 // p == 2a k /= p // k == [sqrt(b^2-4ac)-b]/2a p = x p -= k // p == x-[sqrt(b^2-4ac)-b]/2a result is p ``` (我們有稍微調動計算順序,這麼做主要是為了節省變數用量) 可以觀察我們的計算順序同樣是:`* * * - - √ * / -`,與後序運算的運算符是相同的, 而解析原本數學式的方式則是像//右側內容一樣來解析, 將此計算流程再寫成指令的話,則可以很輕鬆的實現計算數學式的效果 > 通常不會特地轉成後序來看,但如果是一個計算量非常大的式子用此方式分析會很快