什么可以使用std :: numeric_limits <double> :: epsilon()?

Fin*_*ley 2 c++ std numeric-limits

  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); 
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是一个选择声明:

if ( prob_good_model < std::numeric_limits<double>::epsilon() )
{...}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,判断陈述与(或近似)相同

prob_good_model < 0
Run Code Online (Sandbox Code Playgroud)

那么我是否正确以及std::numeric_limits<double>::epsilon()除此之外还可以在哪里使用?

Jer*_*fin 11

epsilon的目的是让你(相当)​​容易找出两个数字之间可以看到的最小差异.

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

如果您尝试使用它而不进行缩放,则可能会出现严重错误(完全无意义)的结果.例如:

if (st::abs(1e-100 - 1e-200) < std::numeric_limits<double>::epsilon())
Run Code Online (Sandbox Code Playgroud)

是的,即使它们相差100个数量级,它也会显示为"真实"(即说两者相等).在另一个方向,如果数字远大于1,则与(未缩放的)epsilon相比相当于说if (x != y)- 它根本没有留下舍入错误的余地.

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

然而,在实际使用中,这是相对较少的实际用途.更实际的数字通常基于输入的精度,以及由于舍入而可能丢失的精度的估计(等等).

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

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

  • 从信号处理工程的角度来看,epsilon看起来像一个“噪底”。将您估计的精度与本底噪声进行比较(在比率的实践中为对数),可以用Decibel为您提供一个数字,您可以将其称为“噪声余量”,并且可以用作检查浮点类型是否足够精确的方法,或者相反发出警报。否则,由于浮点类型太短,您的计算可能会悄无声息地出错。 (2认同)
  • epsilon 是两个数字之间的**最大**相对误差。这意味着乘以数字的大小,就是两个数字之间的**最大**差异。其用途之一是测量计算误差是否“可接受”。如果通过某种方法计算一个值并得到“x”,而通过另一种方法计算得到“y”,则如果“abs(xy)&lt;=epsilon*abs(x)”,则相对误差不大于最大相对误差一个人可以制作“x”的规模。人们可以判断“y”是“y”的可接受的近似值。 (2认同)