[LabVIEW]Formula Node 與 Expression Node 函數詳解與應用指南

更新 發佈閱讀 34 分鐘

這篇文章主要列出 LabVIEW 在 Formula Node 或 Expression Node 裡可使用的函數名稱與其功能說明

Formula Node 使用規則

  • 語法類似 C:支援 ifforwhiledoswitch 等流程控制。
  • 輸入/輸出端口 = 變數,型別由外部 LabVIEW 端決定。
  • 內部變數必須宣告型別(否則會出現 "undefined variable")。
  • 不支援 C 語法的強制型別轉換:像 (int)x(float)y 是錯的,必須用內建函數 (floorceilround) 或運算轉換。
  • 函數名稱必須小寫


型別宣告

Formula Node 支援的型別宣告

    int8        /* 8-bit signed integer */
int16 /* 16-bit signed integer */
int32 /* 32-bit signed integer */
int /* alias for int32 */
uInt8 /* 8-bit unsigned integer */
uInt16 /* 16-bit unsigned integer */
uInt32 /* 32-bit unsigned integer */
float32 /* single precision float */
float64 /* double precision float */
float /* alias for float64 */

範例

int i, j;        /* 32-bit 整數 */
float64 x, y; /* double precision */
float32 f; /* single precision */

運算子與常數

Formula Node 提供了一系列與 C 語言類似的運算子,用於算術、邏輯、位元等運算,其運算優先順序亦與 C 語言相同(由高到低)。同時,節點內也定義了一些常數以供使用。

算術運算子

+(加)、-(減)、*(乘)、/(除)、%(取餘數)。此外,Formula Node 也支援 ** 運算子作為次方(乘冪)計算,例如 x ** 3 表示 x^3。運算時遵循標準的運算優先級(*/% 高於 +-)。算術運算子可用於整數和浮點數,整數除法將截斷小數部分。

遞增遞減

++(遞增)和 --(遞減)運算子可用於數值變數的自增或自減,可在變數前(前置,先運算後取值)或變數後(後置,先取值後運算)使用。例如:i++i 加1,--jj 減1。(注意:Expression Node 不支援 ++/--,但 Formula Node 可以使用。)

比較運算子

==(等於)、!=(不等於)、>(大於)、<(小於)、>=(大於等於)、<=(小於等於)。這些運算會產生布林結果,在 Formula Node 中以數值表示:條件成立則結果為1,否則為0。例如,(a != 0) 若為真則值為1,可用於後續運算或控制流程。

邏輯運算子

&&(邏輯且And)、||(邏輯或Or)、!(邏輯非Not)。&&|| 對應短路求值(從左到右評估,當結果已可確定時就不再評估右),即當結果已確定時會跳過後續運算。任一非零值視為 TRUE,零視為 FALSE。例如,表達式 (x>0 && y>0)xy 均為正時為1,否則為0。

位元運算子

支援按位運算,包括 &(按位且And)、|(按位或Or)、^(按位異或Xor)、~(按位取反Not)。此外還有位元移位運算子:<< 表示將位元向左移(算術左移),>> 表示算術右移。例如:value << 2value 之二進位表示整體左移兩位。

條件運算子(三元運算)

使用 ? : 進行條件運算,其形式與 C 相同:條件表達式 ? 表達式1 : 表達式2。當條件為 TRUE(非零)時,運算結果為表達式1,否則為表達式2。例如:max = (a > b ? a : b); 將較大值賦予 max

指定與複合指定

單一變數指定使用 =,將右側運算結果賦值給左側變數。亦支援複合指定運算,例如 +=-=*=/=%=&=|=^=<<=>>= 以及 **= 等,效果與對應運算後再賦值相同。例如:sum += x; 等價於 sum = sum + x;(注意:在 Formula Node 中,= 為右結合性,即從右往左運算;** 次方運算也是右結合性。)

常數

內建常數只有 pi,代表圓周率 (3.14159…),使用時需小寫拼寫 pini.compi 為區分大小寫的關鍵字,不可寫成 PIPi。公式節點沒有內建 e(自然對數底)常數;若需要可使用函數計算,例如 exp(1) 將得出約 2.718 的值,或自行定義 float64 e = 2.71828; 作為常數使用。

數字常量表示法

支援十進位制的直接數字,例如 103.14 等;也支援其他進位的常量表示法:可用 0x 前綴表示十六進位(例如 0xFF)、0(zero) 前綴表示八進位(如 012),0b 前綴表示二進位(如 0b1011)。浮點數常量可用科學記號,例如 1.5e3 代表 1500。(注意:常量中的小數點只能使用 .,不接受本地化的小數分隔符號,如逗號。)

數學函數庫

Formula Node 提供豐富的內建數學函數,涵蓋基本算術、三角、雙曲線、對數等多種類別,用以簡化各類數學計算。函數名稱均需使用小寫字母,且其行為與 LabVIEW 對應的數學 VI 類似。(請注意,某些函數名稱及行為可能與其他軟體如 Excel、MATLAB 等略有差異。)下表按功能分類列出常用函數,每個函數附有簡要說明和範例:

基本運算與特殊函數

  • abs(x) – 絕對值:傳回 x 的絕對值。例如:abs(-5) 回傳 5。
  • sign(x) – 符號函數:判斷 x 的正負號。若 x > 0 傳回 1;x = 0 傳回 0;x < 0 傳回 -1。可用於快速取得數值的正負號。
  • max(x, y) – 較大值:比較 x 和 y,傳回較大的那一個。例如:max(3, 7) 回傳 7。相對地,min(x, y) 傳回較小值。
  • sqrt(x) – 平方根:計算 x 的平方根。例如:sqrt(9) 回傳 3。若 x 為負,將產生 NaN(非數值)結果。
  • pow(x, y) – 次方:計算 x^y(x 的 y 次方)。這與使用運算子 ** 等價。例如:pow(2, 3) 得 8。
  • rand() – 亂數:產生一個介於 0 與 1 之間的隨機浮點數(不含0與1)。此函數不需參數,每次呼叫會返回不同亂數,例如:r = rand();r 賦值一個隨機值。

三角函數(角度以弧度計)

  • sin(x) – 正弦:傳回角度 x(弧度)的正弦值。例如:sin(pi/2) 回傳 1。
  • cos(x) – 餘弦:傳回 x 的餘弦值。例如:cos(pi) 回傳 -1。
  • tan(x) – 正切:傳回 x 的正切值。例如:tan(pi/4) 回傳 1。需注意在 x = pi/2 (90度)時正切無界(會趨近無限大)。
  • asin(x) – 反正弦:計算 x 的反正弦(arcsin),返回值為弧度。x 必須在 [-1, 1] 之間,例如:asin(0.5) 約回傳 0.5236 (即 30 度)。
  • acos(x) – 反餘弦:計算 x 的反餘弦(arccos),x 範圍 [-1, 1]。如:acos(0) 回傳約 1.5708 (即 pi/2)。
  • atan(x) – 反正切:計算 x 的反正切(arctan),傳回值介於 -pi/2 到 pi/2。如:atan(1) 回傳約 0.7854 (45 度)。
  • atan2(y, x) – 雙參數反正切:計算座標 (x,y) 對應的角度(arctan(y/x)),可判斷象限。傳回值範圍 $-\pi$ 到 $\pi$。例如:atan2(1, -1) 約回傳 2.356 (135 度,在第二象限)。
  • sinc(x) – 規範化 sinc:計算 sin(x)/x 的值。當 x = 0 時定義其值為 1(極限值)。此函數常用於訊號處理。
  • cot(x) – 餘切:計算 x 的餘切(cot = 1/tan x)。例如:cot(pi/4) 回傳 1。x 為 0 或 pi 時餘切無定義。
  • sec(x) – 正割:計算 x 的正割(sec = 1/cos x)。如:sec(0) 回傳 1。若 cos x = 0(如 pi/2)正割無窮大。
  • csc(x) – 餘割:計算 x 的餘割(csc = 1/sin x)。如:csc(pi/2) 回傳 1;sin x = 0 時(如 0 或 pi)餘割無定義。

雙曲函數

  • sinh(x) – 雙曲正弦:計算 [e^x - e^(-x)] / 2。例如:sinh(0) 回傳 0,sinh(1) 約 1.175。
  • cosh(x) – 雙曲餘弦:計算 [e^x + e^(-x)] / 2。如:cosh(0) 回傳 1。
  • tanh(x) – 雙曲正切:計算 sinh(x)/cosh(x)。例如:tanh(0) 為 0,tanh(正/負無限大) 逼近 1 或 -1。
  • asinh(x) – 反雙曲正弦:計算 x 的反雙曲正弦值。例如:asinh(1.175) 回傳約 1(因 asinh(1.175) ≈ 1)。
  • acosh(x) – 反雙曲餘弦:計算 x 的反雙曲餘弦。定義域為 x ≥ 1,例如:acosh(1) = 0。
  • atanh(x) – 反雙曲正切:計算 x 的反雙曲正切。定義域 -1 < x < 1,如:atanh(0.5) 約 0.5493。

指數與對數函數

  • exp(x) – 指數函數:計算 e^x。例如:exp(1) ≈ 2.71828,即常數 e。
  • expm1(x) – e^x - 1:**計算 e^x - 1。當 x 很小時,直接計算 e^x - 1會有精度問題,使用此函數可提高數值穩定性。
  • ln(x) – 自然對數:計算 ln(x)(以 e 為底)。x 必須為正。如:ln(e) 回傳 1。
  • lnp1(x) – ln(1+x):計算 ln(1+x)。當 x 很小時比直接用 ln(1+x) 更精確。例如:lnp1(0.0) = 0
  • log(x) – 常用對數 (Base-10):計算以10為底的對數 log10(x)。如:log(100) 回傳 2。
  • log2(x) – 以2為底對數:計算 log2(x)。例如:log2(8) 回傳 3。

取整與餘數相關函數

  • ceil(x) – 無條件進位:將 x 向上取整到最接近的整數(趨向 +∞ 的方向)。例如:ceil(2.1) 回傳 3;ceil(-2.1) 回傳 -2(-2 比 -2.1 大,向上靠近零)。
  • floor(x) – 無條件捨去:將 x 向下取整到最接近的整數(趨向 -∞ 的方向)。例如:floor(2.9) 回傳 2;floor(-2.1) 回傳 -3。
  • int(x)四捨五入:將 x 四捨五入到最近的整數ni.com(傳回型別仍為浮點)。例如:int(3.6) 回傳 4;int(3.4) 回傳 3;int(-2.5) 回傳 -2 。 *(公式節點的 int 函數採用「至最近整數」規則,.5 恰好在中間的情況下通常遠離0進位。)*
  • intrz(x) – 截斷取整:將 x 趨近0方向取整。這等價於數學上的截斷(Truncate)或 C 語言中將浮點轉為整數的行為。例如:intrz(3.9) 得 3,intrz(-3.9) 得 -3。
  • mod(x, y) – 取餘 (地板除法):計算 x 除以 y 的餘數,其中商向負無窮大方向捨入。這和數學上的 modulo 定義一致。例如:mod(7, 3) 回傳 1;mod(-7, 3) 因 -7/3 的商(向下取整)為 -3,餘數計算得到 2。(因為 -7 = -3*3 + 2)。
  • rem(x, y) – 取餘 (截斷除法):同樣是計算餘數,但使用截斷除法(商向0捨入)。例如:rem(-7, 3) 的商截斷為 -2,餘數為 -7 - (-2*3) = -1。(在非負情況下 modrem 結果相同;負數時可能不同。)
  • getexp(x) – 取得指數:回傳浮點數 x 的以2為底的指數部分。此函數傳回指數 e 的值。例:若 x = 6.0getexp(6.0) 回傳 2。
  • getman(x) – 取得尾數:回傳浮點數 x 的尾數。按照上述例子,getman(6.0) 則回傳 1.5。這兩個函數可用於浮點數的底數-指數分解。

以上函數名稱區分大小寫,且必須以小寫輸入。在 Formula Node 中使用這些函數時,就像在程式碼中呼叫一般函式即可。例如:y = log10(x) + sin(theta);

流程控制語法

公式節點允許使用傳統程式語言的流程控制語法(與 C 語言類似)來實現條件判斷和迴圈等邏輯。這包括 if 條件判斷、各種迴圈 (forwhiledo...while) 以及 switch 多路分支結構等。需要注意的是,控制結構的語法與 C 幾乎相同,但每段區塊需以大括號 {} 劃分(若只有單一語句,允許省略大括號),而 iffor 等結構本身的結尾不需加分號。

if 條件判斷

用於根據條件的 TRUE/FALSE 執行不同分支。

基本語法:

if (條件表達式) {
... // 當條件成立時執行的語句
} else {
... // 當條件不成立時執行的語句
}

else 區塊是可選的,可串接多個 else if 段。範例:

if (temperature > 100) {
status = 2;
} else if (temperature < 0) {
status = -1;
} else {
status = 0;
}

上例根據 temperature 大於100、低於0或介於兩者之間設定不同的狀態值。

for 迴圈

用於執行固定次數的迴圈運算。

語法:

for (初始化; 條件; 遞增) {
... // 迴圈主體
}

其中「初始化」通常用於設定循環計數變數,「條件」為每次迴圈前檢查的條件,不成立則跳出,「遞增」在每次迴圈結束後執行。

範例,計算 0~9 整數的和:

int32 sum = 0;
int32 i;
for (i = 0; i < 10; i++) {
sum += i;
}

執行後 sum 會得到 0+1+...+9 = 45。(注意:for 迴圈的迭代變數需事先宣告型別,如上述 int32 i;

while 迴圈

先檢查條件後執行的迴圈

語法:

while (條件表達式) {
... // 重複執行的區塊
}

只要進入迴圈時條件為真,就會執行迴圈主體,結束後再次檢查條件決定是否繼續。

範例,尋找最小的 n 使得 n! 超過 1000:

int32 n = 1;
float64 factorial = 1;
while (factorial <= 1000) {
n++;
factorial *= n;
}
// 迴圈結束後,factorial > 1000,且 n 為使階乘超過1000的最小值

若初始條件不成立(FALSE),while 迴圈將一次都不執行。

do ... while 迴圈

先執行一次後再檢查條件的迴圈

語法:

do {
... // 先執行一次的區塊
} while (條件表達式);

無論條件真假,區塊內容至少執行一次,之後每次循環結束再評估條件決定是否繼續。

範例,不斷從資料序列取值直到遇到特定終止值:

int32 value;
do {
value = getNextData();
process(value);
} while (value != -1);

上例中,迴圈至少會執行一次 process(),當讀到的 value 等於 -1(假設 -1 為終止符號)時迴圈才停止。

循環控制

在迴圈內,可使用 breakcontinue 關鍵字進行流程控制。break 用於提前跳出最內層的 for/while/do...whileswitchcontinue 則用於跳過迴圈中剩餘的程式並進入下一次迭代。例如,在搜尋目標值時可以在找到時 break 離開迴圈。

switch 多重選擇

用於根據一個整數或字元表達式的值,分支執行多個可能區塊的語句。

語法:

switch (表達式) {
case1:
... // 當表達式==值1時執行
break;
case2:
... // 當表達式==值2時執行
break;
...
default:
... // 預設情況
break;
}

switch 會計算表達式的值,並跳到對應的 case 標籤執行程式碼。每個區塊通常以 break 結束以避免執行串連至下一個 case。default 標籤為可選項,當沒有任何 case 符合時執行。

範例,根據 score 評價等第:

switch(score) {
case 90:
case 100:
grade = "A";
break;
case 80:
grade = "B";
break;
default:
grade = "C";
break;
}

上例中,當 score 為90或100時(示意),等第為 A;為80時等第 B;其他情況為 C。可以看到 case 90: case 100: 連續列出時,兩種情況執行相同區塊。請務必在每個分支末尾使用 break 以避免貫穿至下一分支(除非有意為之)。

陣列操作

公式節點能夠處理陣列型態的輸入和輸出。您可以將 LabVIEW 的數值陣列(1 維或多維)以端口形式連接進入公式節點,在節點內用類似 C 語法的方式讀寫陣列元素。常見的陣列操作包括:利用索引存取元素、使用內建函數取得陣列維度大小,以及透過迴圈處理陣列內容。

輸入陣列

當一個輸入端連接的是陣列時,您可以在公式節點中以方括號索引該陣列的元素。索引從 0 開始(與 LabVIEW 陣列一致)。例如,若輸入變數 A 為一維陣列,則 A[0] 表示第一個元素,A[i] 表示第 i+1 個元素。如果 B 是二維陣列,則可以使用 B[row][col] 存取,其中 B[2][3] 表示第3列第4行的元素。使用多重索引時,每對方括號對應一個維度。請確保索引在有效範圍內,否則在執行時可能產生執行期錯誤或無效結果(LabVIEW 可能返回默認值並不提示錯誤)。

輸出陣列

要從公式節點輸出陣列,有幾種方式:

  • 直接映射輸入:最簡單的情況,是在節點左側有一個輸入陣列,右側建立一個同名的輸出端。此時在程式碼中對該變數的修改將反映在輸出陣列上。例如輸入端和輸出端皆命名為 X,連接一個陣列,那麼在節點內可直接對 X 的元素賦值來改變輸出。由於輸入已定義了長度和型別,這方法能確保輸出陣列大小正確。
  • 自行宣告輸出陣列:或者,您可以在節點內宣告一個陣列型態的輸出變數。例如輸出端命名為 Y,可在程式開頭宣告 float64 Y[10];(宣告一個長度為10的一維陣列)。再在程式中為 Y 的各索引賦值。(注意:此方式必須在 LabVIEW 2019 之後版本使用,較舊版本的公式節點不支援在程式內直接宣告固定大小陣列。)
  • 使用傳入尺寸設定輸出:如果希望輸出陣列與某輸入陣列大小相同,可利用 sizeOfDim 函數取得輸入尺寸,並在迴圈中建立輸出。例如先將輸出端 Y 與輸入端 A 同名(或在程式碼內宣告與輸入同型別的 Y),保證輸出型別為陣列,然後:
int32 len = sizeOfDim(A, 0);
for (int32 i = 0; i < len; i++) {
Y[i] = A[i] * 2;
}

如此即可生成與輸入等長的輸出陣列 Y,其中每個元素是輸入對應元素的兩倍。

sizeOfDim 函數取得長度

Formula Node 提供 sizeOfDim(ary, dim) 函數來取得陣列某維度的長度。ary 為陣列變數名稱,dim 為整數的維度索引(0 表示第一維)。例如:n = sizeOfDim(X, 0); 會將陣列 X 的第一維長度存入 n。若是二維陣列,可使用 sizeOfDim(X, 1) 獲取第二維長度,以此類推。這在需要動態取得陣列大小以迴圈處理時特別有用。

  • 例如,計算一維陣列 A 所有元素的和:
float64 sum = 0;
int32 N = sizeOfDim(A, 0);
for (int32 i = 0; i < N; i++) {
sum += A[i];
}

上例透過 sizeOfDim(A,0) 得知陣列長度,再用 for 迴圈累加每個元素。對於多維陣列,可以巢狀迴圈結合多次 sizeOfDim 使用。

範例,計算 2D 陣列 B 中所有元素的和:

float64 total = 0;
int32 R = sizeOfDim(B, 0); // 列數
int32 C = sizeOfDim(B, 1); // 行數
for (int32 r = 0; r < R; r++) {
for (int32 c = 0; c < C; c++) {
total += B[r][c];
}
}

如上即可遍歷二維陣列的每個元素。

  • 注意事項:在公式節點中陣列索引必須為整數型別,建議使用 int32 或其他整數變數來存放索引值。若使用浮點數作為索引,公式節點可能無法通過編譯或自動截斷為整數。並且,不可對不存在的索引賦值(如超出目前大小的索引),否則可能導致執行錯誤或預期外的行為。如需動態改變陣列大小,應在公式節點外調整後再傳入,或使用 LabVIEW 提供的 Array Resize 等函數。

數值技巧與進階議題

在使用公式節點進行數值計算時,常會遇到需要四捨五入截斷數值的情形,以及正負不同情況下的進位/捨去處理。這裡介紹幾種常見的數值處理技巧。

四捨五入(適用於正負數)

對一個浮點數進行四捨五入,在公式節點中可直接使用 int(x) 函數將其取為最接近的整數。然而,要特別注意負數的情況。例如 int(-2.5) 在公式節點中會回傳 -2(因為 -2.5 與 -2 距離0較近)。若您希望嚴格按照「小數 .5 入」的規則(傳統的四捨五入,即 0.5 無條件進位,-2.5 希望得到 -3),可以採用條件判斷結合 floor/ceil 來實現。

例如:

float64 round_half_up(float64 x) {
return (x >= 0 ? floor(x + 0.5) : ceil(x - 0.5));
}

如上,對非負數加 0.5 後下取整,對負數減 0.5 後上取整,即可實現對稱的四捨五入(正數常規四捨五入,負數亦朝遠離零方向進位)。例如:round_half_up(-2.5) 將得到 -3,round_half_up(2.5) 得到 3。這個技巧在需要與一般數學四捨五入規則一致時特別有用。

無條件進位與截斷

若需要強制朝特定方向取整,可使用 ceilfloor 函數:ceil(x) 總是進位(朝較大的數前進),floor(x) 總是捨去(朝較小的數前進)。兩者在正數時效果類似於一般進位/捨去,但在負數時會產生和直觀相反的結果(因為對負數來說,「較大」反而較接近零)。例如:ceil(-3.2) 得 -3,floor(-3.2) 得 -4。

至於截斷小數部分(朝0方向),可利用 intrz(x) 函數,該函數無論正負都將小數部分切除。例如:intrz(3.9) 回傳 3,intrz(-3.9) 回傳 -3,這相當於數學的「取整到 0」。需要注意,直接將浮點數指定給整數輸出端,LabVIEW 也會執行類似的截斷;但在公式節點中,因不允許 C 式強制轉型,建議直接使用 intrz 函數或透過上述 round_half_up 技巧完成所需的取整操作。

進位與借位計算

在做一些數值處理時,可能需要手動處理進位或借位。例如,將一串數字視為某進位制並加一,或將負數絕對值部分加以處理後還原符號等。這些場合可以結合取整函數與模運算來巧妙處理。例如,要對任意實數進行銀行家舍入(一種特殊的四捨五入,.5 情況下取偶數):可先使用 floor(x + 0.5) 初步四捨五入,再對 .5 情況進行判斷校正;又或者對角度進行歸一化,可利用 mod 函數將角度限制在 0–360 或 -180–180 範圍等等。這些進階技巧雖超出本文範圍,但在公式節點中均可以透過基本函數組合實現。

總之,公式節點提供的數學函式已涵蓋大多數常見的取整和數值操作需求。熟悉這些函式並靈活運用條件表達式,可有效處理正負數的進位與截斷情況。

常見錯誤與除錯指南

在撰寫和使用公式節點時,可能會遇到各種編譯或執行錯誤。以下列出常見錯誤類型、成因及對應的解決方法:

未定義的變數(undefined variable)

這是在編譯階段最常見的錯誤之一。當您在公式節點的程式碼中使用了一個變數,但既沒有在節點邊框上建立相應的輸入/輸出端,也未在程式碼中以型別宣告時,就會導致此錯誤。

例如以下程式將造成 “undefined variable” 錯誤:

y = x * 2;   // x, y 均未宣告或無端口

解決方法:針對每個出現「未定義」的變數名,採取以下措施之一:

  • 建立端口:如果該變數應為輸入或輸出,則在公式節點邊框上右擊選擇 Add Input/Output 並命名為該變數,然後在區塊圖上接上相應的控制或指示元件。
  • 變數宣告:如果該變數只是節點內部使用的臨時變數,則在程式碼開頭以正確的資料型別宣告它(例如 int32 temp;)。宣告後即可在後續程式中使用該變數。

此外,請檢查變數拼寫是否一致(區分大小寫)。Formula Node 中 Datadata 是兩個不同變數,如拼寫不一致也會被視為未定義變數。

資料型別衝突

這種問題通常發生在輸入/輸出端的型別與程式碼中的使用不一致,或輸出端的預設型別不符合期望。例如,若輸入端提供一個整數,而在公式節點中將其賦值給一個未宣告且未建立端口的變數,該變數若被視為隱含輸出將默認為雙精度浮點(Double),導致型別不符預期。另一種情況是,您在節點內宣告了變數型別,但連接該輸出至區塊圖時類型不匹配(例如節點輸出為陣列但接到標量指示器)。

解決方法:

  • 明確定義型別:盡可能在節點內宣告所有非端口變數的型別knowledge.ni.com。如需特定型別的輸出,建議直接在程式碼前宣告(例如 int16 result;)或將相同名稱的輸入端接上所需型別的資料來源來強制該型別。例如,要確保輸出 y 為 I32,可在輸入側也建立一個名為 y 的 int32 控制元並接常數0,這將把 y 的型別鎖定為 int32。
  • 檢查連線一致性:確認公式節點邊框上的輸出資料類型與連接的後續函數或指示器類型一致。LabVIEW 一般會自動在不同數值型別間插入轉型,但在陣列 vs 標量、數值 vs 布林等不相容類型間會報錯。在需要時,可利用 LabVIEW 的「強制型別轉換」節點在公式節點外顯式轉換。

範例: 若公式節點輸出端 Z 預期為整數但實際為預設的 Double(可能因未宣告且無同名輸入導致),會出現型別衝突。此時可在公式節點中加入 int32 Z; 來修正。又或者,建立一個 int32 類型的輸入端 Z 並接上常數0,公式節點將據此將 Z 輸出視為 int32。

語法錯誤

除了變數及型別問題,一般的程式語法錯誤(如漏掉分號、括號不配對、大小寫錯誤等)也會導致公式節點無法編譯。常見的如忘記在語句末加 ;、在 if/for 等結構上誤加了分號或少寫了一個大括號。發生語法錯誤時,LabVIEW 會在公式節點內以 # 標示錯誤位置。您可以按下執行按鈕查看 Error List 了解錯誤描述,並據此修改程式碼。

例如:

  • 錯誤範例:
if (a < b) 
c = a // 缺少分號
d = b;

Error List 可能指出在 c = a 行有語法錯誤。修正方式是在 a 之後補上分號;

  • 錯誤範例:
for i=0; i<10; i++ {   // 語法錯誤,for 語法缺少括號
sum += i;
}

會報導for 語法錯誤,應改為 for (i=0; i<10; i++) { ... }

  • 錯誤範例:

使用了不支援的語法,如 y = (int16)x;,公式節點編譯會報錯「不明符號」或「語法錯誤」。需改用允許的方法(例如 y = intrz(x); 來代替 cast)。

執行期錯誤或意外結果

如果公式節點內存在數學錯誤(如除以零)、陣列索引越界或函數使用不當,可能不會在編譯時報錯,而是在執行時造成不正確的結果甚至 NaN、Inf 等值。此時應檢查:

  • 除零:確保除法運算的分母不為零,或在程式碼中以條件避免(如 if (y != 0) z = x/y; else z = 0;)。
  • 陣列邊界:如前述,確認所有陣列索引皆在範圍內,可利用 sizeOfDim 函數輔助邊界判斷。
  • 函數域值:某些函數對輸入有域限制,如 sqrt(x) 要求 x ≥ 0,log(x) 要求 x > 0,asin(x) 要求 -1 ≤ x ≤ 1 等。輸入超出範圍將回傳 NaN 或無效值,要在使用前加以檢查或處理。

效能考量

雖非「錯誤」,但值得一提:公式節點內過於複雜的計算可能在執行效率上不及等價的內建 LabVIEW 元件組合。若發現公式節點成為效能瓶頸,可考慮改用 LabVIEW 原生函數或平行執行等方式進行優化。

在編輯公式節點時,多加利用 LabVIEW 提供的除錯工具:如開啟 高亮執行(Highlight Execution) 觀察資料流動,或臨時將中間結果輸出為指示器觀察,逐步定位問題。總而言之,謹慎地宣告變數型別、遵守語法規則並檢查邏輯邊界條件,可避免絕大多數公式節點中的常見錯誤,使您的公式節點程式碼正確且穩健。

參考資料

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000x30HCAQ
https://www.ni.com/docs/zh-TW/bundle/labview/page/formula-node-and-expression-node-functions.html?srsltid=AfmBOopbHH-5eICiUYkCM31MKGIqdm3GyMp9Q-SxG3kjwjwI6MIvvsFi
https://www.dmcinfo.com/blog/29886/labview-formula-nodes-faster-or-not/#:~:text=LabVIEW%20Formula%20Nodes%20,solve%20some%20of%20your%20problems
留言
avatar-img
留言分享你的想法!
avatar-img
MC筆記
3會員
15內容數
MC筆記的其他內容
2025/01/17
Modbus 功能碼查詢表格
Thumbnail
2025/01/17
Modbus 功能碼查詢表格
Thumbnail
2025/01/08
本文記錄在 Linux Ubuntu 環境下安裝 GitLab EE 的方法和步驟,包含安裝依賴項、安裝 GitLab 套件、設定 EXTERNAL_URL、SSL/TLS 憑證和 root 密碼等步驟。
Thumbnail
2025/01/08
本文記錄在 Linux Ubuntu 環境下安裝 GitLab EE 的方法和步驟,包含安裝依賴項、安裝 GitLab 套件、設定 EXTERNAL_URL、SSL/TLS 憑證和 root 密碼等步驟。
Thumbnail
2024/12/09
本文介紹如何在LabVIEW環境中設定執行檔以允許多個實例同時運行。透過簡單的步驟修改INI檔,本文將教你如何啟用這項功能,讓你能夠更高效地使用LabVIEW的應用程式。適合需要同時運行多個LabVIEW應用的使用者。
2024/12/09
本文介紹如何在LabVIEW環境中設定執行檔以允許多個實例同時運行。透過簡單的步驟修改INI檔,本文將教你如何啟用這項功能,讓你能夠更高效地使用LabVIEW的應用程式。適合需要同時運行多個LabVIEW應用的使用者。
看更多
你可能也想看
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
還在煩惱平凡日常該如何增添一點小驚喜嗎?全家便利商店這次聯手超萌的馬來貘,推出黑白配色的馬來貘雪糕,不僅外觀吸睛,層次豐富的雙層口味更是讓人一口接一口!本文將帶你探索馬來貘雪糕的多種創意吃法,從簡單的豆漿燕麥碗、藍莓果昔,到大人系的奇亞籽布丁下午茶,讓可愛的馬來貘陪你度過每一餐,增添生活中的小確幸!
Thumbnail
【這個系列,目標是以比較輕鬆的方式讓大家一起學習 Ae 表達式。】 - 第七章-懸賞,快來幫幫村長!學會 Ae 表達式 - function ˙function (函數)是什麼? ˙函數應用在文字圖層上 ˙函數應用在 Position 上 ˙將位置限制在 Composition 範圍內
Thumbnail
【這個系列,目標是以比較輕鬆的方式讓大家一起學習 Ae 表達式。】 - 第七章-懸賞,快來幫幫村長!學會 Ae 表達式 - function ˙function (函數)是什麼? ˙函數應用在文字圖層上 ˙函數應用在 Position 上 ˙將位置限制在 Composition 範圍內
Thumbnail
高中數學主題練習—對數方程式
Thumbnail
高中數學主題練習—對數方程式
Thumbnail
高中數學主題練習—根式化簡
Thumbnail
高中數學主題練習—根式化簡
Thumbnail
註解 & Print & 變數型態
Thumbnail
註解 & Print & 變數型態
Thumbnail
【這個系列,目標是以比較輕鬆的方式讓大家一起學習AE表達式。】 本文是番外篇 3,主要是一些概念的補充,介紹陣列。
Thumbnail
【這個系列,目標是以比較輕鬆的方式讓大家一起學習AE表達式。】 本文是番外篇 3,主要是一些概念的補充,介紹陣列。
Thumbnail
在本章節中,我們將學習JavaScript的基本語法,包括如何註解代碼和如何聲明變數。瞭解這些基礎知識對於進一步學習和使用JavaScript來編寫代碼是非常重要的。
Thumbnail
在本章節中,我們將學習JavaScript的基本語法,包括如何註解代碼和如何聲明變數。瞭解這些基礎知識對於進一步學習和使用JavaScript來編寫代碼是非常重要的。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News