前言
單位轉換是多數系統中會碰到的課題,單純兩個單位之間的轉換還算容易,而多個單位的轉換就有點困難。以「速度」來說,在 m/s
, mph
與 km/h
等數種單位之間互相轉換,排列組合就多達九種以上;而「貨幣」幾乎是每一個國家一種單位,需要在更多單位之間做轉換。如何寫出易於維護可擴展的單位轉換程式碼是非常重要的,這篇文章帶領讀者從數學角度出發,一步步推導出單位轉換公式並將其化為最簡。
直接的做法
以「速度」為例,m/s
, mph
與 km/h
三個單位若需要互相轉換,最直接且暴力的做法是建立一個表記錄下每個單位之間的轉換因子,轉換時只需將原本的值乘以轉換因子 (factor),即可得到進行單位轉換後的數值
1 | const unitFactors = { |
缺點
很多重複的資料:例如
unitFactors['m/s']['mph']
其實就等於1/unitFactors['mph']['m/s']
。難以擴增:若要增加一個單位例如
ft/s
,就要大幅改動轉換因子表如下所示,造成開發者的負擔1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20const unitFactors = {
'm/s': {
..., // (ellipsis)
'ft/s': 3.28084,
},
'mph': {
..., // (ellipsis)
'ft/s': 1.466667,
},
'km/h': {
..., // (ellipsis)
'ft/s': 0.911344,
},
'ft/s': {
'm/s': 0.3048,
'mph': 0.681818,
'km/h': 1.09728,
'ft/s': 1,
}
}
推導單位轉換公式
為了避免之後要償還技術債,不如現在就將單位轉換過程進行簡化。簡化的方式有很多種,這裡會透過數學推導來得到好用的單位轉換公式。
參數說明:
- $v_1$:現在的值。
- $u_1$:現在的單位。
- $v_2$:單位轉換後的值。
- $u_2$:轉換後的單位。
- $f_{12}$:單位由 $u_1$ 轉換為 $u_2$ 時,所需乘的轉換因子。
- $u_0$:基底單位。
- $f_{01}$:單位由 $u_0$ 轉換為 $u_1$ 時,所需乘的轉換因子。
- $f_{02}$:單位由 $u_0$ 轉換為 $u_2$ 時,所需乘的轉換因子。
可列出方程式
我們的目標就是算出 $v_2$
這時我們知道單位轉換的公式為 $v_1$ 乘以 $u_1/u_2$,將分數部分上下同除一個基底單位 $u_0$
$u_0$ 用來作為轉換的一個中間單位,它可以是任何單位如 m/s
, mph
或 km/h
,接下來將會演示如何使用此公式
使用公式實作單位轉換
這裡選定 m/s
基底單位 $u_0$,先建立以 m/s
為基底單位的轉換因子表
1 | const unitFactors = { |
最後實作單位轉換函數
1 | function unitConvert(value, from, to) { |
問題的改善
沒有重複的資料:重複的資料已經隱含在 $1/f_{01}$ 之中,因此不需要再多記倒數後的結果。
容易擴充的轉換因子表:若要多加一個單位例如
ft/s
,只需增加一行1
2
3
4const unitFactors = {
..., // (ellipsis)
'ft/s': 3.28084,
}