【发布时间】:2020-06-02 14:34:43
【问题描述】:
我有一个double 的向量。这些数字以0.001 之类的精度给出,这意味着这些数字以千分之一单位的精度给出。例如,我希望有123456789.012 但不是123456789.01231。在实践中,由于浮点运算,实际数字更像123456789.01199999452,这是123456789.012 的有效和最接近的表示。
我想有力地测试我的数字是否真的具有应有的准确性。例如,如果我的123456789.01231 与0.001 的准确性不匹配,我想发出警告。对我来说另一个有效的选择是找到给定数字的准确性。
到目前为止,我所做的是测试(x - offset)/accuracy 是否为整数。偏移量可防止整数溢出。实际上,由于浮点运算,它不能是整数,所以我添加了一个任意阈值。它有效,但在我看来它不是一个强大的解决方案。
dx = (x[i]-offset)/accuracy;
ix = std::round(dx);
if (std::abs(dx - ix) > 1e-5)
throw exception("...");
此过程不涉及任何字符串。这些数字来自二进制文件或运行时计算。准确度由用户给出,预计数字符合此准确度。在我之前的123456789.012 示例中,我知道这个数字实际上并不存在,但123456789.01199999452 是有效的,因为它是double 的最佳表示。但是123456789.01231(实际上是123456789.01230999827)是无效的,因为它不是3位四舍五入值的最佳表示。
【问题讨论】:
-
乘以 1000 并检查小数部分是否符合阈值 - 例如添加 0.001 并检查结果是否小于 0.01,但不确定实际值。
-
假设这些数字是以文本形式“给出”的,你可以在转换前读取字符串并验证格式。
-
你想要做的是违背浮点数的本质。不仅数字不能用浮点数准确表示,实际精度取决于数字大小。您正在寻找的可能是一种专为满足您的目的而设计的定点格式。 en.wikipedia.org/wiki/Fixed-point_arithmetic
-
@JRR 以防万一您想检查计算的数学错误,这与您描述的任务完全不同。在这种情况下,您可以将 FP 数分解为符号、指数和尾数,并测试尾数的符号、指数和 N 个最高有效位是否等于预期值。这里,N 表示所需的精度。
-
我会看看 x 和 std::nexttoward(x,0) 之间的区别,并检查它是否小于 1/512。这样,您就会知道,即使该值没有准确表示,它也由该类型可以容纳的最接近的数字表示。
标签: c++ floating-point floating-accuracy integer-arithmetic