計(jì)算階乘:移位寄存器與條件終止全解析)
簡(jiǎn)介《LabVIEW應(yīng)用技術(shù) n的階乘WHILE課堂實(shí)訓(xùn)》是面向LabVIEW初學(xué)者的實(shí)操文檔專(zhuān)為計(jì)算機(jī)、自動(dòng)化類(lèi)課程設(shè)計(jì)可幫助讀者快速掌握?qǐng)D形化編程中While循環(huán)結(jié)構(gòu)的應(yīng)用。資源包僅含1個(gè)docx文檔大小66KB內(nèi)容完整覆蓋前面板控件創(chuàng)建、程序框圖連線(xiàn)、循環(huán)條件設(shè)置、邊界值處理與代碼優(yōu)化等關(guān)鍵環(huán)節(jié)并附有實(shí)訓(xùn)項(xiàng)目單和總結(jié)分析適合直接用于課堂作業(yè)、實(shí)驗(yàn)報(bào)告或自學(xué)參考。目前已有689人學(xué)習(xí)。文檔以“輸入整數(shù)n—循環(huán)迭代—輸出n!”為主線(xiàn)詳細(xì)說(shuō)明了While循環(huán)的退出判斷機(jī)制、乘法與遞減等數(shù)值運(yùn)算VI函數(shù)的使用方法同時(shí)針對(duì)n等于0或1的特殊情況給出處理方案并展望了錯(cuò)誤處理、交互擴(kuò)展與計(jì)算結(jié)果可視化等改進(jìn)方向。對(duì)于初識(shí)LabVIEW的學(xué)生來(lái)說(shuō)這份材料既能加深對(duì)迭代結(jié)構(gòu)的理解也有助于提升算法實(shí)現(xiàn)、邏輯構(gòu)建和程序調(diào)試等綜合能力是實(shí)驗(yàn)室實(shí)訓(xùn)和入門(mén)自學(xué)的實(shí)用資料。1. 用 WHILE 循環(huán)在 LabVIEW 里算 n!先想清楚什么時(shí)候停很多人第一次在 LabVIEW 里寫(xiě)階乘會(huì)把 FOR 循環(huán)當(dāng)成默認(rèn)選擇反正已知 n循環(huán) n 次就行。但課堂實(shí)訓(xùn)偏偏要求用 WHILE 循環(huán)這個(gè)要求看似繞路其實(shí)是在逼你處理兩件 FOR 循環(huán)替你隱藏了的事循環(huán)什么時(shí)候繼續(xù)、什么時(shí)候必須停。WHILE 循環(huán)沒(méi)有內(nèi)置的計(jì)數(shù)上限它只認(rèn)條件接線(xiàn)端上的布爾值——這個(gè)設(shè)計(jì)讓它在「次數(shù)未知、條件動(dòng)態(tài)變化」的場(chǎng)景里遠(yuǎn)比 FOR 靈活但代價(jià)是你得自己維護(hù)計(jì)數(shù)器、自己寫(xiě)終止條件。好消息是階乘本身恰好是學(xué)習(xí) WHILE 循環(huán)的最佳載體你既能練會(huì)移位寄存器又能搞明白條件接線(xiàn)端的兩種配置差異還能把 n0、負(fù)數(shù)、溢出這些邊界一起想清楚。這篇就按課堂實(shí)訓(xùn)的完整路徑走一遍。2. WHILE 循環(huán)的迭代機(jī)制以及階乘為什么天然適合它2.1 WHILE 與 FOR 的結(jié)構(gòu)差異誰(shuí)在決定循環(huán)次數(shù)LabVIEW 的 FOR 循環(huán)在進(jìn)入前就確定迭代次數(shù)接線(xiàn)端N一旦給出數(shù)值循環(huán)體就固定跑這么多趟中途無(wú)法因數(shù)據(jù)變化而提前退出。WHILE 循環(huán)則不同它的迭代次數(shù)完全由條件接線(xiàn)端的布爾值決定循環(huán)每執(zhí)行完一次就把條件值重新讀一次為真就繼續(xù)為假就停止。這意味著循環(huán)次數(shù)在執(zhí)行過(guò)程中是開(kāi)放的可以在某一輪循環(huán)里根據(jù)當(dāng)前計(jì)算結(jié)果決定是否終止。從原理上講這正好對(duì)應(yīng) C 語(yǔ)言的while與do-while的區(qū)別。LabVIEW 的 WHILE 循環(huán)默認(rèn)是「先執(zhí)行、后判斷」這更接近 C 的do-while無(wú)論條件真假循環(huán)體至少執(zhí)行一次。如果你的計(jì)算邏輯允許 n0 時(shí)直接輸出 1這個(gè)「至少執(zhí)行一次」的特性就需要你主動(dòng)處理而不能指望循環(huán)幫你跳過(guò)。理解這個(gè)底層區(qū)別才能解釋為什么同樣的階乘代碼在 n0 時(shí)會(huì)輸出錯(cuò)誤結(jié)果。2.2 階乘的迭代關(guān)系從遞歸式到循環(huán)體的映射階乘的定義是 n! n × (n-1)!這是典型的遞歸關(guān)系。但在循環(huán)實(shí)現(xiàn)里我們不用遞歸而是把它改寫(xiě)成迭代積的形式初始化累乘結(jié)果 result 1從 i 1 開(kāi)始每輪執(zhí)行 result result × ii 自增 1直到 i n 時(shí)停止迭代過(guò)程n5 result 1 i 1 → result 1 × 1 1 i 2 → result 1 × 2 2 i 3 → result 2 × 3 6 i 4 → result 6 × 4 24 i 5 → result 24 × 5 120 i 6 5 → 停止輸出 120循環(huán)要素在階乘中的對(duì)應(yīng)物說(shuō)明循環(huán)條件i n為真時(shí)繼續(xù)累乘循環(huán)體result result × i累乘動(dòng)作每次迭代都執(zhí)行狀態(tài)保持result 與 i 兩個(gè)變量需要跨循環(huán)保留不能每輪重置終止條件i n計(jì)數(shù)超過(guò)目標(biāo)值后停止難點(diǎn)在于「狀態(tài)保持」。result和i都必須在每一輪循環(huán)之間傳遞數(shù)值如果每輪從框外重新讀取輸入累乘就永遠(yuǎn)只是單次乘法。LabVIEW 中跨循環(huán)傳遞狀態(tài)的機(jī)制是移位寄存器這是整個(gè)小節(jié)的關(guān)鍵。2.3 移位寄存器WHILE 循環(huán)里跨輪傳值的唯一常規(guī)手段移位寄存器由循環(huán)邊框左側(cè)的「上方接線(xiàn)端」和右側(cè)的「下方接線(xiàn)端」構(gòu)成一對(duì)。右側(cè)端子存放的是當(dāng)前輪次結(jié)束時(shí)寫(xiě)入的值下一輪開(kāi)始時(shí)由左側(cè)端子讀出。對(duì)階乘來(lái)說(shuō)result的右端子上做result × i再寫(xiě)回左端子初始連接輸入1就能做到每輪結(jié)果都建立在前一輪之上。左端子初始化→ result 1 循環(huán)體new_result result × i 右端子寫(xiě)入→ new_result 下一輪左端子讀到的值 → new_result這里有個(gè)常見(jiàn)錯(cuò)誤有人把初始化直接接到右端子的輸入上導(dǎo)致每一輪循環(huán)結(jié)束都把 result 重置成 1循環(huán)跑完輸出的永遠(yuǎn)是 n。記住一個(gè)判斷方法接在循環(huán)框左邊端子上的默認(rèn)值只生效一次接在右邊端子上的值負(fù)責(zé)「提交」當(dāng)前結(jié)果。這個(gè)關(guān)系在任何帶狀態(tài)的循環(huán)程序里都成立不只是階乘。3. 動(dòng)手搭一個(gè) WHILE 階乘計(jì)算器前面板與程序框圖完整走一遍3.1 新建 VI 與控件選擇前面板三件套打開(kāi) LabVIEW新建一個(gè)空白 VI。前面板上需要三個(gè)控件一個(gè)數(shù)值輸入控件用于輸入 n、一個(gè)數(shù)值顯示控件用于輸出結(jié)果、一個(gè)停止按鈕用于手動(dòng)終止循環(huán)??丶恢迷凇缚丶惯x板 →「數(shù)值」 →「數(shù)值輸入控件」和「數(shù)值顯示控件」按鈕在「布爾」→「停止按鈕」。停止按鈕不是裝飾。WHILE 循環(huán)沒(méi)有自動(dòng)附加的終止機(jī)制如果循環(huán)條件判斷的是「i n」這種正邏輯萬(wàn)一 n 設(shè)成負(fù)數(shù)或代碼寫(xiě)錯(cuò)導(dǎo)致 i 永遠(yuǎn)追不上閾值你只能靠這個(gè)按鈕強(qiáng)制退出。養(yǎng)成「凡是 WHILE 循環(huán)必留一個(gè)手動(dòng)停止入口」的習(xí)慣調(diào)試時(shí)會(huì)少很多強(qiáng)行關(guān)閉 LabVIEW 的場(chǎng)面。按鈕默認(rèn)的機(jī)械動(dòng)作是「釋放時(shí)觸發(fā)」適合保持按下?tīng)顟B(tài)我會(huì)把按鈕的機(jī)械動(dòng)作改成「開(kāi)關(guān)」這樣按一次保持 True再按一次恢復(fù) False條件判斷更直觀(guān)。n 的輸入控件建議設(shè)置數(shù)據(jù)范圍右鍵 →「屬性」→「數(shù)據(jù)輸入」→最小值設(shè)為 0最大值根據(jù)數(shù)據(jù)類(lèi)型設(shè)成 20 以?xún)?nèi)。這樣就把非法值限制在源頭而不必在代碼里寫(xiě)一堆判斷。3.2 程序框圖連線(xiàn)順序移位寄存器、計(jì)數(shù)器與條件端切到程序框圖按以下順序連線(xiàn)從 WHILE 循環(huán)邊框左側(cè)引出移位寄存器右鍵邊框 →「添加移位寄存器」左側(cè)默認(rèn)值接常量1作為 result 的初始化值。在循環(huán)內(nèi)部放置兩個(gè)數(shù)值常量1一個(gè)作為計(jì)數(shù)器 i 的初值一個(gè)作為每次循環(huán)的步長(zhǎng)。把 n 輸入控件從框外接到循環(huán)框內(nèi)注意它并不經(jīng)過(guò)移位寄存器——n 在整個(gè)循環(huán)過(guò)程中是只讀的。循環(huán)體內(nèi)做一個(gè)乘法運(yùn)算移位寄存器左端子的當(dāng)前值 × 當(dāng)前計(jì)數(shù)器 i結(jié)果連到移位寄存器右端子。計(jì)數(shù)器加 1把 i 的當(dāng)前值需要再一個(gè)移位寄存器來(lái)保持加上步長(zhǎng) 1結(jié)果寫(xiě)回計(jì)數(shù)器的右端子。條件接線(xiàn)端右鍵選擇「真時(shí)停止」Continue if True 的反向邏輯將比較表達(dá)式i n的結(jié)果取反后接入。數(shù)據(jù)流連接順序括號(hào)內(nèi)為節(jié)點(diǎn)作用 (數(shù)值常量 1) → 移位寄存器左端子 [result 初始化] (n 輸入控件) → 循環(huán)框內(nèi) [只讀不寫(xiě)回] 移位寄存器左端子 → 乘法節(jié)點(diǎn)輸入a 計(jì)數(shù)器 i 的移位寄存器左端子 → 乘法節(jié)點(diǎn)輸入b 乘法節(jié)點(diǎn)輸出 → 移位寄存器右端子 [result 當(dāng)前輪積] 計(jì)數(shù)器值 → 加1節(jié)點(diǎn) → 計(jì)數(shù)器右端子 [i 自增] 比較節(jié)點(diǎn) i n比較 i 和 n→ 條件接線(xiàn)端真時(shí)停止注意乘法節(jié)點(diǎn)的兩個(gè)輸入必須都來(lái)自循環(huán)內(nèi)部的狀態(tài)不能在框圖外邊直接把 n 拉去和 result 相乘——雖然數(shù)學(xué)上等價(jià)但這樣寫(xiě)的語(yǔ)義是把整個(gè)循環(huán)變成了「每次都乘以同一個(gè)數(shù)」完全違背迭代累乘的算法結(jié)構(gòu)。課堂實(shí)訓(xùn)里我會(huì)要求學(xué)生把乘法輸入源寫(xiě)清楚來(lái)源就是為了避免這種「運(yùn)氣好算對(duì)、改個(gè)輸入就錯(cuò)」的代碼。3.3 條件接線(xiàn)端的兩種配置真時(shí)停止與真時(shí)繼續(xù)LabVIEW WHILE 循環(huán)的條件接線(xiàn)端是一個(gè)綠色圓形圖標(biāo)右鍵可以選擇兩種條件類(lèi)型條件類(lèi)型判斷邏輯循環(huán)何時(shí)停止適用場(chǎng)景真時(shí)停止Stop if True條件是 True 則停止條件表達(dá)式為真時(shí)退出比較結(jié)果為「達(dá)到目標(biāo)」時(shí)最直觀(guān)真時(shí)繼續(xù)Continue if True條件是 True 則繼續(xù)條件表達(dá)式為假時(shí)退出條件本身就是「繼續(xù)」語(yǔ)義時(shí)回到階乘要表達(dá)的終止條件是「i n」。如果選「真時(shí)繼續(xù)」循環(huán)框內(nèi)的表達(dá)式要寫(xiě)i n把這個(gè)條件原樣接進(jìn)去如果選「真時(shí)停止」表達(dá)式要寫(xiě)i n結(jié)果為真時(shí)退出。兩種寫(xiě)法等價(jià)但很多人會(huì)栽在「邏輯取反」上條件是i n選擇了「真時(shí)停止」卻沒(méi)有取反結(jié)果循環(huán)在 i 小于等于 n 的每一輪都退出一次乘法都跑不了。我的習(xí)慣是優(yōu)先使用「真時(shí)停止」把「什么時(shí)候?!箤?xiě)成正向表達(dá)式因?yàn)槿说乃季S更容易描述「?!苟皇恰咐^續(xù)」。3.4 運(yùn)行驗(yàn)證用 5、0、1 三個(gè)輸入分別看輸出完成連線(xiàn)后CtrlR 運(yùn)行 VI依次輸入 5、0、1 并觀(guān)察結(jié)果n5輸出應(yīng)為 120n1輸出應(yīng)為 1n0輸出可能有兩種如果你正確處理了初始條件輸出是 1如果你沒(méi)做處理可能輸出 1也可能輸出 0取決于移位寄存器的初值設(shè)定n0 這個(gè)坑在第一次實(shí)訓(xùn)里幾乎必踩。WHILE 循環(huán)至少執(zhí)行一次所以當(dāng) n0 時(shí)循環(huán)體仍會(huì)執(zhí)行result 1 × 1結(jié)果是 1 再乘以 i1得到 1——恰好碰對(duì)了。但如果把計(jì)數(shù)器 i 的初值設(shè)成 0n0 時(shí)會(huì)執(zhí)行result 1 × 0 0輸出就成了 0。這個(gè)細(xì)節(jié)決定了你的階乘能不能正確處理邊界輸入也是后面章節(jié)輸入校驗(yàn)的基礎(chǔ)。4. 邊界處理與子 VI 封裝讓階乘程序不再只是課堂作業(yè)4.1 輸入校驗(yàn)負(fù)數(shù)、超大輸入、非法字符串怎么攔截前面板的數(shù)據(jù)范圍限制擋得住鼠標(biāo)操作擋不住程序化調(diào)用時(shí)的負(fù)數(shù)和超大值。在循環(huán)開(kāi)始前必須對(duì) n 做三層校驗(yàn)小于 0階乘在實(shí)數(shù)域無(wú)定義直接報(bào)錯(cuò)。大于類(lèi)型上限32 位有符號(hào)整數(shù)最大只能存12! 479001600超過(guò) 12 的 n 會(huì)讓數(shù)據(jù)溢出結(jié)果是錯(cuò)的但程序不報(bào)錯(cuò)。非整數(shù)輸入實(shí)數(shù)控件允許 5.5 這樣的值循環(huán)里 i 從 1 累加可能永遠(yuǎn)追不上 5.5 導(dǎo)致死循環(huán)。校驗(yàn)流程偽代碼 if n 0 → 錯(cuò)誤簇輸出「輸入不能為負(fù)數(shù)」 if n 12 → 錯(cuò)誤簇輸出「32位整數(shù)無(wú)法容納該階乘值」 if n 不是整數(shù) → 錯(cuò)誤簇輸出「輸入必須為整數(shù)」 if 任一校驗(yàn)失敗 → 跳過(guò)循環(huán)直接輸出錯(cuò)誤簇和默認(rèn)結(jié)果 0校驗(yàn)條件校驗(yàn)位置失敗處理方式n 0循環(huán)外進(jìn)入循環(huán)前錯(cuò)誤簇返回「輸入不能為負(fù)數(shù)」n 12循環(huán)外進(jìn)入循環(huán)前錯(cuò)誤簇返回「結(jié)果超出整數(shù)類(lèi)型范圍」n 非整數(shù)循環(huán)外進(jìn)入循環(huán)前錯(cuò)誤簇返回「輸入必須為整數(shù)」n 0 或 1循環(huán)內(nèi)作為分支直接返回 1不進(jìn)入累乘第四行可以做一個(gè)優(yōu)化當(dāng) n0 或 n1 時(shí)結(jié)果恒為 1可以不進(jìn)循環(huán)直接連一條快捷路徑輸出。這樣程序在邊界輸入下運(yùn)行效率更好也避免 WHILE 循環(huán)「至少執(zhí)行一次」的語(yǔ)義干擾。4.2 將計(jì)算邏輯封裝成子 VI輸入輸出端子的設(shè)置課堂作業(yè)寫(xiě)到單個(gè) VI 里沒(méi)問(wèn)題但實(shí)訓(xùn)的進(jìn)階要求是把階乘做成可復(fù)用的子 VI供其他程序調(diào)用。創(chuàng)建子 VI 的要點(diǎn)在于圖標(biāo)和連接器端口把前面板控件整理成標(biāo)準(zhǔn)布局左側(cè)放輸入n右側(cè)放輸出結(jié)果、錯(cuò)誤簇。右鍵前面板右上角圖標(biāo)選擇「編輯圖標(biāo)」畫(huà)一個(gè)識(shí)別度高的標(biāo)記比如n!。在「連接器」視圖里點(diǎn)擊左鍵選擇輸入對(duì)應(yīng)的格子再點(diǎn)擊前面板上的 n 控件建立關(guān)聯(lián)同理把結(jié)果和錯(cuò)誤簇關(guān)聯(lián)到輸出格。設(shè)計(jì)連接器時(shí)我會(huì)把錯(cuò)誤簇放在最下方結(jié)果放右側(cè)中部n 放左側(cè)遵循「錯(cuò)誤在底、數(shù)據(jù)在中」的習(xí)慣。這樣調(diào)用時(shí)連線(xiàn)習(xí)慣一致不容易接錯(cuò)。子 VI 的輸入要設(shè)置為「必選」避免調(diào)用方忘記接線(xiàn)導(dǎo)致默認(rèn)值悄悄生效。子 VI 內(nèi)部結(jié)構(gòu)建議沿用條件接線(xiàn)端的配置但把停止按鈕移除——子 VI 運(yùn)行時(shí)應(yīng)由內(nèi)部條件自然終止不需要外部手動(dòng)干預(yù)。如果保留手動(dòng)按鈕調(diào)用方會(huì)看到一個(gè)無(wú)法感知的「掛起狀態(tài)」只能在調(diào)試時(shí)發(fā)現(xiàn)是按鈕沒(méi)復(fù)位。4.3 大數(shù)階乘WHILE 循環(huán)配合高精度數(shù)據(jù)類(lèi)型的做法當(dāng) n 超過(guò) 2020! 243290200817664000064 位有符號(hào)整數(shù)也已經(jīng)接近上限9.22 × 10^18。再往上就只能用擴(kuò)展精度LabVIEW 的「擴(kuò)展精度浮點(diǎn)數(shù)」能表示更大的數(shù)值范圍但精度會(huì)丟失大數(shù)階乘會(huì)被舍入成近似值。n21 時(shí) 準(zhǔn)確值51090942171709440000 32位整數(shù)溢出運(yùn)行時(shí)不報(bào)錯(cuò)結(jié)果錯(cuò)誤 64位整數(shù)51090942171709440000恰好可用超過(guò)則溢出 雙精度浮點(diǎn)5.10909E19前6位準(zhǔn)確后續(xù)位被舍入 擴(kuò)展精度浮點(diǎn)51090942171709440000比雙精度多保留約10位有效數(shù)字目標(biāo) n 值推薦數(shù)據(jù)類(lèi)型原因n ≤ 1232 位有符號(hào)整數(shù)12! 可完整容納內(nèi)存占用小n ≤ 2064 位有符號(hào)整數(shù)20! 恰好小于 2^63n ≤ 170雙精度浮點(diǎn)數(shù)171! 超出雙精度表示上限n 170不建議計(jì)算浮點(diǎn)溢出為無(wú)窮大無(wú)實(shí)際意義這個(gè)表格的結(jié)論是如果你想擴(kuò)大計(jì)算范圍不是把 WHILE 循環(huán)改復(fù)雜而是先換數(shù)據(jù)類(lèi)型。循環(huán)結(jié)構(gòu)本身不受 n 大小的任何影響它只認(rèn)「i 是否大于 n」這個(gè)比較結(jié)果。這也是 WHILE 循環(huán)相比 FOR 循環(huán)的優(yōu)勢(shì)之一——循環(huán)次數(shù)在理論上不受數(shù)據(jù)類(lèi)型限制真正的天花板在數(shù)據(jù)通道不在控制結(jié)構(gòu)上。5. 課堂實(shí)訓(xùn)的驗(yàn)證技巧與高頻踩坑點(diǎn)5.1 用高亮執(zhí)行觀(guān)察每一輪迭代的狀態(tài)變化LabVIEW 的「高亮執(zhí)行」Highlight Execution是查看 WHILE 循環(huán)數(shù)據(jù)流的最佳工具。開(kāi)啟后點(diǎn)擊運(yùn)行你會(huì)看到數(shù)據(jù)點(diǎn)在節(jié)點(diǎn)之間逐跳移動(dòng)移位寄存器的值會(huì)以氣泡形式顯示當(dāng)前內(nèi)容。驗(yàn)證階乘時(shí)我會(huì)在每一輪循環(huán)暫停下來(lái)記錄輪次移位寄存器 result 值計(jì)數(shù)器 i 值是否繼續(xù)111繼續(xù)222繼續(xù)363繼續(xù)4244繼續(xù)51205停止如果發(fā)現(xiàn)第二輪 result 直接跳成 2說(shuō)明移位寄存器的初始化接錯(cuò)了左端子可能接到了乘法節(jié)點(diǎn)的輸出而不是常量 1。高亮執(zhí)行能讓你最快定位這類(lèi)「邏輯對(duì)、數(shù)據(jù)錯(cuò)」的問(wèn)題。5.2 條件接線(xiàn)端最常見(jiàn)的三種錯(cuò)誤第一種條件類(lèi)型選反。實(shí)際跑了 1 輪就退出或者完全不退出。把「真時(shí)停止」和i n直接相連就是典型的 1 輪退出——因?yàn)榈谝惠?i1 5 為真真時(shí)停止直接終止。解決方法是把條件表達(dá)式取反或者改成「真時(shí)繼續(xù)」。第二種把 n 輸入錯(cuò)接進(jìn)移位寄存器右端子。框外的 n 每輪都保持同一個(gè)值如果你把它接到移位寄存器右端子意味著每一輪結(jié)束都被重置成 n。假設(shè) n5循環(huán)第一輪 result1×11寫(xiě)回時(shí)被 n 覆蓋成 5下一輪左端子讀到的不是上一輪的積而是 5。最后輸出的結(jié)果就完全不是階乘。第三種循環(huán)體里放了一個(gè)「等待」節(jié)點(diǎn)但沒(méi)接毫秒值。WHILE 循環(huán)會(huì)以極快速度執(zhí)行沒(méi)有延時(shí)時(shí)幾乎占滿(mǎn) CPU 單核。實(shí)訓(xùn)時(shí)如果在循環(huán)內(nèi)不加延時(shí)整個(gè)程序框圖會(huì)顯得「卡死」其實(shí)是從不停止的高速迭代。在循環(huán)體內(nèi)加一個(gè)「等待ms」節(jié)點(diǎn)設(shè)置 10 到 100 毫秒既能控制 CPU 占用也讓高亮執(zhí)行時(shí)的狀態(tài)變化看得清。5.3 驗(yàn)證算法正確性的一個(gè)快速技巧不拿手算的 5 去驗(yàn)證因?yàn)?120 太好算就算代碼有邊界錯(cuò)誤也可能撞對(duì)。我會(huì)要求實(shí)訓(xùn)中額外輸入 7結(jié)果 5040和 9結(jié)果 362880這兩個(gè)值能檢驗(yàn)移位寄存器是否真的在跨輪累乘因?yàn)?7! 和 9! 在錯(cuò)誤實(shí)現(xiàn)下很難碰巧正確。再把輸入切到 0 和 1記錄輸出應(yīng)該都是 1以驗(yàn)證邊界處理分支是否生效。最后強(qiáng)制輸入一次 13確認(rèn)程序是在報(bào)錯(cuò)還是算出一個(gè)負(fù)數(shù)——如果是負(fù)數(shù)說(shuō)明沒(méi)做溢出檢查你應(yīng)該暴力不合格。本文還有配套的精品資源點(diǎn)擊獲取