---
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,*,/,-$
我們可以將其依序解析:

> 在這裡要特別注意根號(√)是一個單變數函式(一元運算),他只會用掉一個數
如果不是很知道該怎麼轉換的可以利用這個線上轉換器來輔助:
[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
```
(我們有稍微調動計算順序,這麼做主要是為了節省變數用量)
可以觀察我們的計算順序同樣是:`* * * - - √ * / -`,與後序運算的運算符是相同的,
而解析原本數學式的方式則是像//右側內容一樣來解析,
將此計算流程再寫成指令的話,則可以很輕鬆的實現計算數學式的效果
> 通常不會特地轉成後序來看,但如果是一個計算量非常大的式子用此方式分析會很快