空一個框,可見卡片就變成了 0 張
這個頁面的輸入是分子、分母兩欄一行的網格,預設三行 1/2、1/3、1/4。先讓它算成功,再把任意一個框整個清空,露出來的輸出卡片還剩幾張?四組清空方式答案一樣:0 張——沒有結果卡,也沒有錯誤卡,錯誤文案是個空字串。
計算函數一進來就把結果卡和異常卡都設成 display:none,再逐行 parseInt;只要有一個框解析出 NaN 就直接 return,那兩行 display 再也沒被改回來。失敗在這裡不是走一條提示分支,而是退回兩張卡都藏著的初始狀態。
| 輸入狀態 | 可見卡片 | 錯誤文案 |
|---|---|---|
| 3 行頁清掉第 1 行分子 | 0 張 | 0 碼元 |
| 3 行頁第 3 行兩個框都清 | 0 張 | 0 碼元 |
| 第 2 行分母填 0 | 1 張錯誤卡 | 20 碼元 / 48 位元組 |
| 只剩 1 行且兩框都空 | 1 張錯誤卡 | 15 碼元 / 39 位元組 |
唯一會說話的是分母為 0 那條:文案逐字「⚠️ 第 N 個分數的分母為 0,請修正」,單數字時 20 碼元 / 48 位元組,N 從 1 數起,第 1、2、3、5 行的分母為 0 分別報 1、2、3、5。而 NaN 與 0 同時在場時,報不報要看行序——空框在第 1 行時函數第 1 行就返回,第 2 行那個 0 完全不提。
圖 1:可見卡片張數的對照——空框與 2 行全空都是 0 張
靜默那一次,舊結果和舊文案都不清
照步驟走一遍。分數通分計算這頁能寫入的出口只有 8 個 id:兩行 1/2、1/3 算成功,結果區寫著「1/2 = 3/6」「1/3 = 2/6」;第 2 行分母改 0,換成 1 張錯誤卡;再清空第 1 行分子,卡片歸 0,而 DOM 一樣沒清——那句 20 碼元的文案仍在、公分母格仍是 6、結果區仍是那 2 行、複製文字仍是 26 碼元、過程區還掛著 6 行舊過程。複製按鈕寫在結果卡內部,卡一藏這份舊文字也就點不到。
parseInt 不帶基數:7 個靜默、22 個截斷
兩個框都按 parseInt(value) 讀取,沒寫第二個基數參數。29 個測試串裡 7 個給 NaN 走靜默那一途——空字串、3 個空格、".5"、"abc"、"Infinity"、"NaN"、"½";剩下 22 個全部無聲截斷。
| "1.5" | "3.9999" | "-1.9" | "1e3" | "0x10" | "08" | "12abc" | "1,5" |
|---|---|---|---|---|---|---|---|
| 1 | 3 | -1 | 1 | 16 | 8 | 12 | 1 |
分母位餵 "1.5" 時公分母是 3,結果行逐字「1/1 = 3/3」「1/3 = 1/3」——頁面按 1/1 通分,框裡的 1.5 不回寫;"1e3" 同樣按 1/1 走,一個 1000 被當成 1。瀏覽器能否把 "0x10"、"12abc" 留在 type=number 的框裡本批未實測,能確定的是框值為空字串時 parseInt 必給 NaN。
負分母:負號的三種命運
公分母那一側取絕對值,倍數那一側帶符號。1/2 配 1/-3 那組公分母 6,結果行「1/-3 = -2/6」,過程行寫「分母清單: 2, 3」「LCM(2, 3) = 6」——負號在分母清單這行就消失,倍數那行明寫「分子分母同乘 -2=-2/6」。三行 1/-2、1/-3、1/-4 給公分母 12、結果 -6/12、-4/12、-3/12。0 乘負倍數得負零、字串化成 0,於是寫「0/-2 = 0/4」;同負的 -2/-3 負負得正,輸出「-2/-3 = 10/15」。
鏈式 LCM,與 990 行不是最簡
多個分母的公分母是從 1 起 reduce 的鏈,摺疊次數恆等於分母個數:2、3、4 的中間值走 2、6、12;12、18、30 走 12、36、180,中間那個 36 不是結果的因子;3、5、7、11 給 1155;2、3、5、7、11、13 給 30030。
化簡那一步在程式碼裡不存在,全文沒有第二次求最大公約數。1/2 與 2/4 同列時公分母 4,輸出「1/2 = 2/4」「2/4 = 2/4」,第二條是原分母已等於公分母的恆等行。樣本放大到 576 組兩行網格、1152 行結果:990 行的新分子與公分母還有公因子、537 組至少一行不是最簡、453 組兩行都不是、180 組含恆等行;兩個原分數都已最簡的 289 組裡,通分後仍不是最簡的有 250 組。這是對輸出文字計數,不是給使用者的建議。
「分數4」和「分數2」是同一行
行標籤是「分數」加一個只增不減的計數器,刪行不回收編號。首屏 3 行標「分數1、分數2、分數3」,刪第 2 行再加 1 行,標籤變「分數1、分數3、分數4」——行數還是 3,最大編號已經 4;過程區用的是陣列下標,那第三行在過程裡被叫作「分數2」。反覆加刪 20 輪,行數恆為 3、標籤跑到「分數21、分數22、分數23」、計數 23;只有「重置」把計數歸 0,標籤才重新從 1 數到 3。
刪行按 cd-row- 拼原始編號找 DOM,找不到就跳過、不報錯——對已刪那行再點一次行數變化 0,編號 99 同樣沒動靜,可末尾那次重算寫在 if 外面,什麼都沒刪成也照樣算一遍。加行反過來不算:實測一組行數 4、標籤「分數1、分數4、分數5、分數6」,頁面仍亮著那句 15 碼元的提示,結果卡裡留著上一輪的 2 行「1/2 = 2/4」「1/4 = 1/4」和公分母 4。
複製文字的段數是行數加 1
複製取隱藏 span 的 textContent,首行恆為「公分母: 」、之後每條分數一行,所以段數總是行數加 1:2 行 3 段 26 碼元、3 行 4 段 40 碼元、4 行 5 段 55 碼元、8 行 9 段 137 碼元、10 行 11 段 193 碼元。組裝時每行末尾都各加一個換行,寫進去前有一次 trim:41 碼元 / 47 位元組變 40 碼元 / 46 位元組,切分段數從 5 變 4,差值恰好 1 碼元 / 1 位元組;串首是「公」沒有前導空白,末字元是數字。12 行分母排到 12 時公分母 27720,第一條寫著「1/1 = 27720/27720」。
常見問題
Q:清空一個框,頁面為什麼什麼都不顯示?
兩張卡在函數開頭就被藏掉,解析出 NaN 時直接 return,沒有一處再把它們亮回來,所以可見卡片是 0 張;分母填 0 才有那句 20 碼元的提示。
Q:結果不是最簡分數,是不是算錯了?
這一頁只做通分那步乘法,輸出的是同分母形式,576 組樣本裡 990 行還有公因子。通分之後怎麼接著加減、約分放在事前還是事後,另一篇 分數加減的過程 說過。
Q:分母很大時會不會出問題?
本頁實測到的量級只有 12 行分母排到 12 時那個 27720,更大的輸入不在這一頁的測量範圍裡;超大數上最小公倍數的浮點表現,另一篇 先乘後除的中間量 量過。