杂记 › 技术笔记 › 空一个框就 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