std::numeric_limits<double>::epsilon() 有什么用?

What can std::numeric_limits<double>::epsilon() be used for?

  unsigned int updateStandardStopping(unsigned int numInliers, unsigned int totPoints, unsigned int sampleSize)
    {
        double max_hypotheses_=85000;
        double n_inliers = 1.0;
        double n_pts = 1.0;
        double conf_threshold_=0.95

        for (unsigned int i = 0; i < sampleSize; ++i)
        {
            n_inliers *= numInliers - i;//n_linliers=I(I-1)...(I-m+1)
            n_pts *= totPoints - i;//totPoints=N(N-1)(N-2)...(N-m+1)
        }
        double prob_good_model = n_inliers/n_pts;

        if ( prob_good_model < std::numeric_limits<double>::epsilon() )
        {
            return max_hypotheses_;
        }
        else if ( 1 - prob_good_model < std::numeric_limits<double>::epsilon() )
        {
            return 1; 
        }
        else 
        {
            double nusample_s = log(1-conf_threshold_)/log(1-prob_good_model);
            return (unsigned int) ceil(nusample_s); 
        }
    }

这里是一个选择语句:

if ( prob_good_model < std::numeric_limits<double>::epsilon() )
{...}

据我理解,判断语句与(或近似)相同

prob_good_model < 0

所以我说得对不对,除此之外还有什么地方可以使用std::numeric_limits<double>::epsilon()

epsilon 的意义在于让您(相当)容易地找出两个数字之间可以看到的最小差异。

虽然您通常不会完全按原样使用它。您需要根据要比较的数字的大小来缩放它。如果您有两个大约 1e-100 的数字,那么您将使用以下顺序的值:std::numeric_limits<double>::epsilon() * 1.0e-100 作为您的比较标准。同样,如果你的数字在 1e+100 左右,你的标准就是 std::numeric_limits<double>::epsilon() * 1e+100.

如果您尝试在不缩放的情况下使用它,您可能会得到非常不正确(完全没有意义)的结果。例如:

if (std::abs(1e-100 - 1e-200) < std::numeric_limits<double>::epsilon())

是的,这将显示为 "true"(即,说两者相等),即使它们相差 100 个数量级。在另一个方向上,如果数字远大于 1,则与(未缩放的)epsilon 进行比较等同于说 if (x != y)——它根本没有舍入误差的余地。

至少根据我的经验,为浮点类型指定的 epsilon 并不是经常有用。通过适当的缩放,它会告诉您给定大小的两个数字之间可能存在的最小差异(对于特定的浮点实现)。

然而,在实际使用中,实际用处相对较小。更实际的数字通常基于输入的精度,以及您可能因四舍五入(等等)而损失的精度量的估计值。

例如,假设您开始时测量的值精度为百万分之一,并且您只进行了少量计算,因此您认为由于舍入误差可能损失了多达 2 位数的精度.在这种情况下,您关心的 "epsilon" 大约是 1e-4,按比例缩放到您正在处理的数字的大小。也就是说,在那种情况下,您可以期望 4 位精度的数量级是有意义的,因此如果您看到前四位有差异,则可能意味着值不相等,但如果它们不同仅在第五位(或更晚的)数字中,您应该将它们视为相等。

您使用的浮点类型可以表示(例如)16 位精度的事实并不意味着您使用的每个测量都将接近精确——事实上,这种情况相对较少基于物理测量的任何东西都有希望接近那个精确度。但是,它确实限制了您对计算的期望值——即使您从一个精确到 30 位的值开始,计算后您可以期望的最大值将定义为std::numeric_limits<T>::epsilon.