Try   HackMD

一、數值計算操作(Arithmetic Operation)

1. 記分板計算(Scoreboard Arithmetic Operation)

  • 記分板僅能儲存整數(integer),且數值儲存範圍為 [-2147483648, 2147483647]=[-231, 231-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的值,唯一的雙向操作(bi-operation)

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 數值區間中

請注意,在 細談指令分析─記分板比較 中有提及到以下效率優化的規則:
若比較的scoreboard數量只有1個時,使用execute if score會比用selector還要有效率,
但若比較的scoreboard數量為2個以上時,請盡可能避免使用execute if score來比較


如何快速解析運算式的順序

有時候觀察一個數學式子,像是一個

4x(180x)40500x(180x)之類的式子都要觀察老半天,
或是看到別人寫的計算數學的函數又不知道該怎麼樣快速看的話,
我們在這裡會提供一個可以快速解析的方式

在這裡要提及數學式結構的概念:

表達式 expression 格式 範例
前序 prefix + a b * + 2 3 7
中序 infix a + b ( 2 + 3 ) * 7
後序 postfix a b + 2 3 + 7 *

中敘式是我們一般解數學題目時會使用的方式,
而轉成後序式可以讓電腦更方便計算,也不用考慮到括弧的問題

此概念之後在學習程式的「資料結構」部分時會再提及到一次


轉換中序式 為 後序式(Infix Expression to Postfix Expression)

假設現有一式:

xb+b24ac2a

首先步驟是將其攤平:

x(b24acb)/2a
後續轉換的步驟是從左往右解析,而轉換後的後序式會是這樣:

x,b,b,,4,a,,c,,,,b,,2,a,,/,

我們可以將其依序解析:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在這裡要特別注意根號(√)是一個單變數函式(一元運算),他只會用掉一個數

如果不是很知道該怎麼轉換的可以利用這個線上轉換器來輔助:
Data Structure : Infix Postfix Prefix - Converter & Evaluator


知道了後序式之後能做什麼?

當然就是直接寫出指令了,還能做甚麼?
如果還不是很了解的話,可以把「後序運算的轉換過程」看成是一個「計算流程」,
每當遇到一個運算符(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

(我們有稍微調動計算順序,這麼做主要是為了節省變數用量)
可以觀察我們的計算順序同樣是:* * * - - √ * / -,與後序運算的運算符是相同的,
而解析原本數學式的方式則是像//右側內容一樣來解析,
將此計算流程再寫成指令的話,則可以很輕鬆的實現計算數學式的效果

通常不會特地轉成後序來看,但如果是一個計算量非常大的式子用此方式分析會很快