4

尝试进行服务器端验证(PHP),其中有 HTM5 数字输入:

<input ... min="1" max="20" step="0.1" />

浏览器将允许您输入诸如“10.5”之类的值,但是如何在 PHP 中进行双重检查呢?对于那些不会进行验证的浏览器(以及您不应该信任来自浏览器的数据的事实)。

if (fmod(floatval($value), 0.1) == 0) {
    // valid
}

这不起作用,因为 fmod() 在这种情况下返回“0.099999 ...”,根据:

为什么 0.5 mod 0.1 在不同编程语言中的结果不同?

您可以将 $value 乘以 10,并使用 1(而不是 0.1)的模数检查,因此您可以进行整数数学运算……但是如果步长为 0.01 或 0.003,会发生什么情况?

4

1 回答 1

2

如果数字将存储为引擎盖下的浮点数,它将始终四舍五入到最接近的可表示数字。

您可以接受该值作为浮点数,然后简单地进行如下检查:

// get the nearest multiple of $step that is representable in float
$normalized = round($number, $allowed_digits); // for steps like '0.1', '0.01' only
$normalized = round($number / $step) * $step;  // works for any arbitrary step, like 0.2 or 0.3

// verify if they are not too different, where EPSILON is a very small constant
// we cannot directly == as the calculations can introduce minuscule errors
if (abs($normalized - $number) > EPSILON)
   die("Did not validate.");

或者,您可以简单地将来自客户端的值视为字符串,并验证字符串中使用的位数(稍后转换为浮点数)。如果您想 100% 确定用户输入的是 0.01,而不是 0.099999999999(四舍五入到与 0.01 相同的值),您应该这样做。

于 2012-10-15T16:37:38.527 回答