C中双数据类型的最大精度是多少?

时间:2012-08-20 12:42:34

标签: c floating-point double-precision

为了比较C中的两个双重类型变量,我定义了#define EQUALITY_EPSILON = 1e-8。我正在进行如下比较:

if((img_score[i] - img_score[j]) >= EQUALITY_EPSILON){
    // handle for ith score greater than jth score
}
else if((img_score[j] - img_score[i]) >= EQUALITY_EPSILON){
    // handle for ith score smaller than jth score
}
else{
    // handle for ith score equal to jth score
}

我面临的问题是我的代码中的分数非常小,因此对于EQUALITY_EPSILON = 1e-8,在某些情况下,比较的结果证明是相等的。我的问题是我可以设置EQUALITY_EPSILON有多小?

3 个答案:

答案 0 :(得分:13)

浮点数不会均匀地分布在数字线上。它们在0附近非常密集,随着幅度的增加,两个可表达值之间的“delta”增加:

                               0
|      |     |    |   |  |  | ||| |  |  |   |    |     |      |

这意味着,对于较小的数字,您需要使用较小的“epsilon”。

编辑:并且您允许的错误或epsilon应该与您在比较的值中预期的错误处于相同的范围内。即由于浮点运算导致的错误制作它们。请参阅下面的评论,了解原因。 / EDIT )。

math.h中的nextafter可以获得您需要使用的'epsilon'类型的公平指示:

nextafter(x, y)返回x之后的下一个可表示值,沿着数字线行进,方向为y

另一种方法是计算img_score[i]img_score[j]之间的幅度差异,并查看它与img_score[i]或{{1}的幅度相比有多小}。多小了?你需要决定。

答案 1 :(得分:2)

您不应该使用epsilon的绝对值。选择的值应该与您要比较的值相关。

例如,您可以将最小值(最接近零)除以一百万并使用其绝对值。

这是否合适的选择取决于为达到这些值而执行的操作。它可能并不适合所有情况。

答案 2 :(得分:1)

double的最小绝对值是2 ^ { - 1023},大约是10 ^ { - 308}。但是只有53位用于存储尾数(有效数字所在的部分)。如果您事先知道差异的近似值,那么您的epsilon的差值几乎可以低至2 ^ { - 53}倍。如果您事先不知道,您应该将您的epsilon构建为其中一个差异的百分比。

请注意,下降到2 ^ { - 53}倍的差异是双精度限制所造成的限制。如果你减去的两个值彼此非常接近,那么你的差值中有少于53个有效位,那么你的epsilon只能低至差值的2 ^ { - x}倍,其中x是有效值的数量不同之处。