<form>
<input type="number" step="1" required>
<input type="submit">
</form>
在上面的代码段中,如果您插入
0.0000001
输入数字时,您不能提交表单:“ step”属性可以防止这种情况。
但是如果你插入
0.00000001
它可以在Chrome / Chromium中使用!为什么在验证输入时似乎只读取前七个小数位?是否在任何地方对此进行了记录,并且我可以做些什么来防止这种情况发生?
我测试了Firefox,它不接受任何此类值。
为了澄清起见0.30000000000000004 === 0.1+0.2
,这里不是常见的陷阱,因为这仅发生在小数点后16位。上面的输入值失败,保留8位小数。
虽然这肯定是您所拥有数字的错误,但实际上可以防止其他步骤/值组出现问题。分数舍入存在一些核心问题,因此要进行完美的步骤验证并非那么容易,至少不是那样精确。实际上,如果您查看Firefox源代码,则可以找到以下注释https://dxr.mozilla.org/mozilla-central/source/dom/html/HTMLInputElement.cpp#4654:
在处理小数时,下面可能会出现舍入问题,但是在ECMAScript为我们提供十进制数类型之前,我们可以忽略它。
因此,问题不仅仅与Chrome有关。但是,让我们从您描述的错误开始。如果查看Chromium源代码,则可以看到在step_range处理中,有一个名为AcceptableError的方法,该方法可以调整值和针对该步骤调整的值之间的差。参见https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/html/forms/step_range.cc?l=60。此可接受的错误定义为:
the step value / 2^24 (in the source code UINT64_C(1) << FLT_MANT_DIG)
这给出了第一步:
1 / 16777216 = 0.000000059604645
因此,在您的原始示例中,即使该数字不具有余数,该数字也将有效。计算余数的公式为:
value - step * Math.abs(Math.round(value / step));
因此,例如,如果您输入2.000000059604644,则余数为:
2.000000059604644 - 1 * Math.abs(Math.round(2.000000059604644))
= 2.000000059604644 - 2
= 0.000000059604644
0.000000059604644低于0.000000059604645,因此它将进行验证。2.000000059604646不会。
<form>
<input type="number" step="1" required>
<input type="submit">
</form>
您可以尝试使用更大的数字,例如,采取167772167的步骤。这将产生一个可接受的错误:
16777217 / 16777216 = 1.000000059604645
值16777218的余数为:
16777218 - 16777217 * Math.abs(Math.round(1.000000059604645 ))
= 16777218 - 16777217
= 1
<form>
<input type="number" step="16777217" required>
<input type="submit">
</form>
该误差在您可接受的错误1下,因此它将进行验证。
所以这是错误。它允许复仇的目的是容忍某些步骤和值,这些步骤和值由于十进制运算的精度损失而无法在应有的时间进行验证。而在Firefox之类的浏览器中,这正是发生的情况。某些值/步骤对在何时应验证。
例如,采取853.2394的步长和495714162280.48785的值。这肯定可以验证,因为:
495714162280.48785 / 853.2394 = 580978987
如果您在Firefox中尝试过,它将无法验证。但是在Chrome中,由于第一种情况下会导致错误的容忍度,因此它可以进行验证。
<form>
<input type="number" step="853.2394" required>
<input type="submit">
</form>
因此,最终,此错误与小数运算的已知问题有关,这并不精确。经典示例是0.1 + 0.2 = 0.30000000000000004。后台发生的事情更加复杂和精确,但是处理小数计算的问题会导致这些问题,并使其很难在每种情况下都避免。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句