雜記 › 技術筆記 › 空一個框就 0 張卡:分數通分頁的靜默失敗、跳號的「分數N」與 990 行不約分

空一個框就 0 張卡:分數通分頁的靜默失敗、跳號的「分數N」與 990 行不約分

實測分數通分頁:清空任一框時解析出 NaN 直接返回,兩張卡都已藏好,可見卡片 0 張且舊結果與舊文案殘留;parseInt 截斷 22 串,負分母的倍數帶符號,576 組樣本裡 990 行不是最簡,行標籤還會跳號。

空一個框,可見卡片就變成了 0 張

這個頁面的輸入是分子、分母兩欄一行的網格,預設三行 1/2、1/3、1/4。先讓它算成功,再把任意一個框整個清空,露出來的輸出卡片還剩幾張?四組清空方式答案一樣:0 張——沒有結果卡,也沒有錯誤卡,錯誤文案是個空字串。

計算函數一進來就把結果卡和異常卡都設成 display:none,再逐行 parseInt;只要有一個框解析出 NaN 就直接 return,那兩行 display 再也沒被改回來。失敗在這裡不是走一條提示分支,而是退回兩張卡都藏著的初始狀態。

輸入狀態可見卡片錯誤文案
3 行頁清掉第 1 行分子0 張0 碼元
3 行頁第 3 行兩個框都清0 張0 碼元
第 2 行分母填 01 張錯誤卡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 完全不提。

四條失敗路徑,頁面各自亮幾張卡 任一框為空 → isNaN 直接 return 可見 0 張 分母為 0 → 錯誤卡 可見 1 張,20 碼元 只剩 1 行全空 → 行數檢查 可見 1 張,15 碼元 2 行全空 → 先過行數再過解析 可見 0 張 0 張這一途,舊結果與舊文案都留在 DOM 裡

圖 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"
13-11168121

分母位餵 "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,更大的輸入不在這一頁的測量範圍裡;超大數上最小公倍數的浮點表現,另一篇 先乘後除的中間量 量過。

📎 相關文章

替換次數報 5 還是報 1:批次尋找替換的三個開關與零寬匹配實測 2026-11-07 刪右側給空串、截右側還整行:text-line-ops 的碼元口徑與越界不對稱實測 2026-11-07 120 個詞槽、15 條整句、1 句寫死的開頭:lorem-ipsum 的詞表清點與重複片段實測 2026-11-05 SVG 預覽的尺寸到底聽誰的:顯示框恆等於容器,刪掉 viewBox 之後 r=1 實測 2 像素 2026-11-05 文字分列後空欄位沒丟:a,,b 照留、列號越界填空、填 0 或 abc 退回全部列實測 2026-11-05