Show HN:我做了一个支持区间不交集运算的计算器
文章摘要
作者 fouronnes3(Victor Poughon)过去几周一直在研究区间算术(interval arithmetic),他发现这是一个”有大量精彩研究但远没有得到应有关注”的领域。这个 Show HN 是他对此的一次实践——一个开源的交互式计算器,实现了”区间并集算术”(interval union arithmetic)。
作者在帖子里详细解释了核心动机:标准区间算术在处理”除以包含 0 的区间”时表现极差。比如计算 1 / [-1, 2],标准算术只能给出 [-∞, +∞] 或者声称运算未定义——两种结果都基本无用。但真正正确的答案是 [-∞, -1] U [0.5, +∞],即两个不相交区间的并集。这个结果非常有价值,因为它能确切告诉你 [-1, 0.5] 这段值是不可能出现的。
但这个”不相交并集”的结果不再是一个区间,破坏了标准区间算术的封闭性(你无法继续把它代入下一步计算)。解决思路是把整个算术系统建立在”区间的不相交并集”之上。这个数学基础来自 Schichl、Domes、Montanher 和 Kofler 在 2017 年发表的论文《Interval Unions》。这种推广也能解决 tan() 这类不连续函数的处理问题。
技术实现上,作者用 TypeScript 写了一个零依赖的库 not-so-float,基于 IEEE 754 双精度浮点数(JS 原生 Number 类型)实现”外向舍入”(outward rounding),在浮点误差存在的情况下保证区间结果的精确性。这个 Show HN 在 HN 上获得 314 分、54 条评论,吸引了不少数学和数值计算爱好者。
HN 评论精华
作者 fouronnes3 的延伸阐释:他特别强调,外向舍入(用来对抗精度问题)只是区间算术最广为人知的特性,但”包含性质”(inclusion property)其实在每个尺度都奏效。比如 50 * (10 + [-1, 1]) = [450, 550] 这样优雅的计算。增加并集层让我们能定义出”平方函数的真正反函数”——你知道吗,sqrt 并不是!试试 sqinv(64) 就明白了(应该返回 [-8] U [8])。
他还透露这个计算器其实是为了测试他另一个项目”反向更新电子表格”(bidicalc)所做的副产品。
关于 IEEE 1788 标准的讨论:thekoma 询问作者实现的算术与 IEEE 1788《区间算术标准》有什么不同。作者回答:”我没特别熟悉 IEEE 1788。我用的是 JS Number(双精度 IEEE 754),由于 JS 不支持外向舍入,我用 TypedArray 做了位级别的 hack 来实现 C 的 nextafter() 等价函数。我主要参考了 Hickey & van Emden 的论文。真正的难点是为区间除法生成完整的测试用例,要拿到 100% 覆盖率太难了!”
iamwil:推荐了 Matt Keeter 在隐式曲面(implicit surfaces)领域的工作,他用区间数学做了优化。这是区间算术在实际应用领域(计算机图形学、CAD)的真实案例。
memalign:分享了他自己用区间算术做的图形计算器(formulagraph),并提供了实现细节链接。0xml 注意到这有点像经典的 GrafEq——一个用区间算术绘制隐函数图像的老牌软件。
关于区间记号法的有趣讨论:globular-toast 提到他对作者使用 [a, b] 记号有点疑惑,”以为标准是圆括号 (a, b)”。qbit42 解释:”圆括号在美国是标准,但 [a, b] 在法国和其他地方使用。” meindnoch 进一步举出经典的歧义例子:”(0, 1) 是开区间还是 2D 向量?这就是 Bourbaki 引入 ]0,1[ 记号的原因。”
noncovalence 的两个尖锐问题:(1)能否扩展到多值函数?比如 asin(1) 应该返回 [π/2, π/2] + n[2π, 2π] 的完整集合而不是单值;(2)”用户输入的数字被解释为不包含 IEEE 754 最近值的最小区间”——这种描述方式逻辑上需要再确认,他理解的应当是 IEEE754(input) ± ε。这是数学上对作者实现细节的严格审视。
整体反响:技术圈对作者扎实的数学基础和严谨的工程实现给予了高度评价,区间算术在数值方法、CAD、约束求解等领域有真实价值,这个项目让更多人能直观体验到它的魅力。