【问题标题】:Floating point rounding errors in Knockout.ValidationKnockout.Validation 中的浮点舍入错误
【发布时间】:2014-07-07 22:55:30
【问题描述】:

我有一个步长为 0.01 的数字输入,被 Knockout “监视”,并且 Knockout.validation 插件也检查该值。

在测试输入以确保它给出适当的错误消息时,我发现某些输入会导致验证消息。例如,值 -0.14 将导致错误:“该值必须增加 0.01”。

有问题的 Knockout.Validation 代码是:

return utils.isEmptyVal(val) || (val * 100) % (step * 100) === 0;

对于 val = -0.14step = 0.01,浮点运算会导致此行返回 false,这意味着 Knockout.Validation 将 -0.14 视为无效输入。这只是一个例子,有很多情况会发生这种情况。对于-0.14 的情况,(val * 100) % (step * 100) 的结果是-1.7763568394002505e-15

有没有一种简单的方法可以修补此代码?在所有情况下以下是否足够:

return utils.isEmptyVal(val) || parseInt(val * 100) % parseInt(step * 100) === 0;

或者我应该进行范围检查吗?

【问题讨论】:

  • 您的修复也将允许step = 0.011。有问题吗?
  • 步骤不会改变,而且我相信 Knockout.Validation 之前不支持超过 2 位小数(仅通过查看代码)。
  • 你得到浮点错误的值了吗?针对合理的 epsilon 进行测试可能就足够了:Math.abs((val * 100) % (step * 100)) < 0.000001(或附近)。它需要abs,因为您的论点可能是否定的。
  • 什么时候 val 被转换成浮点数?有什么方法可以访问原始用户输入?

标签: javascript floating-accuracy knockout-validation


【解决方案1】:

在类似的情况下,我发现this issue 中的代码解决了我的问题。

有问题的核心代码似乎与您提出的解决方案非常相似,尽管我认为使用 parseFloat 而不是 parseInt 是有充分理由的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多