前天改一个表单校验,用户填数量填了个负一,后端直接把库存算成负数发出去,仓管一脸懵。回头一查,校验规则里只写了大于零,没把零本身挡住,正实数这个边界又把人坑了。

先把定义理清楚。实数就是数轴上所有的点,包括整数、小数、分数,也包括负数和零。正实数就是大于零的那部分,注意零不算正数,负号更不算,所以取值区间是从零往右开,零点本身取不到。

正和「非负」已经是两码事

很多人混着用,正实数表示大于零,非负实数表示大于等于零,差的就是那个零。做年龄、价格、件数这种字段,通常要的是正实数,零得挡掉。做差额、偏移量这类,零是合法值,就得用非负。写校验前先想清楚这个字段到底允不允许零。

正则和代码里怎么写才不容易漏

HTML 输入框可以直接用 type 等于 number 配 min 属性,但 min 是包含式的,设成零其实放过了零,要挡零得设成 0.0001 那种小正数,或者干脆在 JS 里判。正则想匹配正实数,常见写法是排除零和负号,别用只写数字的那种,它会把零和负数都放进来。

Java 里可以用 BigDecimal 的 compareTo 和零比较,返回正数才是正的。Python 里写大于零的条件时,记得浮点数比大小有时候会抖,做金额用 Decimal 更稳。

  • 价格和数量:要求严格大于零,零就是脏数据
  • 坐标和偏移:零合法,用非负判断
  • 科学计算:注意浮点误差,边界值别用等号硬比

还有个细节容易被忽略,负零在浮点里存在,虽然它等于零,但打印出来带个负号,看着别扭,输出前顺手归一化一下。

再补个实际会碰到的边界,科学计数法。用户在输入框敲了 1e3,看着像带字母,其实解析出来是一千,是正实数。有些校验只认纯数字字符串,会把它误判成非法,这时候得先按数值解析再判断正负,而不是拿字符串硬套规则。

还有单位换算带来的零问题。毫米换成米,一点五毫米出来是零点零零一五,正常处理;但换算后又四舍五入到两位,正好成了零,本来合法的正数被舍成了零,日志里就冒出个不该出现的零值。这类地方要么多留几位小数,要么在入库前单独拦一道。

说到底就一句,写规则先把零归哪边定死,再写大于还是大于等于,边界想明白,后面省一堆对账。