C 建议的双精度最小ε是多少?

C 建议的双精度最小ε是多少?,c,floating-accuracy,C,Floating Accuracy,我试图在C语言中创建一个高斯消除器。为此,我需要不时地检查矩阵在数值上是否奇异:如果某个数字(double)非常小 我的问题是,如果我尝试这样做: if(0 == matrix->items[from]){ fprintf(stderr,"Matrix is still singular after attempting pivot. Exitig.\n"); } 这永远不会成为现实。由于double的不精确性,它永远不会精确到0。然而,当试图运行程序时,像这样的情况会用

我试图在C语言中创建一个高斯消除器。为此,我需要不时地检查矩阵在数值上是否奇异:如果某个数字(double)非常小

我的问题是,如果我尝试这样做:

if(0 == matrix->items[from]){
        fprintf(stderr,"Matrix is still singular after attempting pivot. Exitig.\n");
}
这永远不会成为现实。由于double的不精确性,它永远不会精确到0。然而,当试图运行程序时,像这样的情况会用inf或NaN填充数字,这取决于与它及其组合相乘还是相除

为了过滤这些,我需要如下内容:

#define EPSILON very_small
// rest of the code
if(matrix->items[from] < EPSILON){
     ...singular
}
对不起,如果我不够清楚,英语不是我的母语

谢谢你的回复

我需要检查矩阵在数值上是否奇异

通常,这是通过防止
double
溢出来检测的

// Check if 1.0/determinant will overflow.
if (fabs(determinant) <= 1.0/(0.99*DBL_MAX)) {
  Handle_Singular_Case()
} else {
  one_over_det = 1.0/determinant;
}
然而,这是非常上下文敏感的


然而OP真正的问题肯定在这里:“当试图运行程序时,像这样的情况会用inf或NaN填充数字,这取决于是用它和它的组合相乘还是相除。”。可以使用各种技术来避免此问题,例如使用进行消除

为了解决这个问题,最好发布代码和示例数据

我需要检查矩阵在数值上是否奇异

通常,这是通过防止
double
溢出来检测的

// Check if 1.0/determinant will overflow.
if (fabs(determinant) <= 1.0/(0.99*DBL_MAX)) {
  Handle_Singular_Case()
} else {
  one_over_det = 1.0/determinant;
}
然而,这是非常上下文敏感的


然而OP真正的问题肯定在这里:“当试图运行程序时,像这样的情况会用inf或NaN填充数字,这取决于是用它和它的组合相乘还是相除。”。可以使用各种技术来避免此问题,例如使用进行消除


为了解决这个问题,最好发布代码和示例数据。

请不要编写
如果(0==matrix->items[from])
,它真的很难看。现代编译器会抱怨,如果你不小心使用赋值而不是比较,那么这不再是一个“好”做法。@Olaf为什么这是唯一正确的值?@IharobAlAsimi我相信
如果(value==VARIABLE)
(例如
5==I
)被称为yoda语句,它不一定难看,但是它肯定会让你的代码被嘲笑。
epsilon
的值可能取决于上下文:不是你能得到多近,而是你需要多近。DBL_epsilon是1+DBL_epsilon减去一个位==1.0的值。它太小了,不能用作草率等式测试的一般ε。我使用FLT_EPSILON,但更多是因为名称可用,而且我使用它的原因很明显,而不是通过严格的测试。请不要编写
,如果(0==matrix->items[from])
,它真的很难看。现代编译器会抱怨,如果你不小心使用赋值而不是比较,那么这不再是一个“好”做法。@Olaf为什么这是唯一正确的值?@IharobAlAsimi我相信
如果(value==VARIABLE)
(例如
5==I
)被称为yoda语句,它不一定难看,但是它肯定会让你的代码被嘲笑。
epsilon
的值可能取决于上下文:不是你能得到多近,而是你需要多近。DBL_epsilon是1+DBL_epsilon减去一个位==1.0的值。它太小了,不能用作草率等式测试的一般ε。我使用FLT_EPSILON,但更多的是因为它的名字是可用的,我使用它的原因很明显,而不是通过严格的测试。关于构造算法以实现数值稳定性的良好观察,特别是关于为此目的的部分旋转。将数学转换成好的程序远不如将公式转换成所选语言的语法那么简单。@JohnBollinger-True。矩阵运算的接受性计算隐藏了各种陷阱。多年来,我在部分旋转代码方面一直存在一个bug,比如查找最大元素、使用的代码
abs()
、错误的
fabs()
——以及启用的警告不足。直到所有的|元素|都小于1.0时,错误才真正显现出来-之后发生了0.0的div。
(1.0*DBL_EPSILON)
的意义是什么?乘以1真的有什么作用吗?@rici可以解释
(1.0*DBL\u EPSILON)
。通常需要的ε是接近1.0的一些小因子,可能在0.5到2.0的范围内。与许多此类问题一样,该值是特定于应用程序的。类似于
(0.99*DBL\u MAX)
,它可以是
(0.999999…*DBL\u MAX)
,以确保值刚好更小,以避免在反向计算中出现舍入错误。对于答案的第二个一半,我将删除它,因为它是一个微妙的增强,它从答案的主旨中消失了。我认为这是我错过的一些C++微妙之处:-如果这个想法是允许一种方法来选择一个数字,靠近代码> dBLY-EpSalon < /C>这意味着,
DBL_EPSILON
中有一些东西使它适合于这个目的。但它的实际含义没有关系,所以它只是一个任意的小数字,也可以是2**-69或2**-42。(至少,我认为是这样,你的评论“通常是错误的”,这表明我们同意。)关于构造算法以实现数值稳定性的良好观察,特别是关于为此目的的部分旋转。将数学转换成好的程序远不如将公式转换成所选语言的语法那么简单。@JohnBollinger-True。矩阵运算的接受性计算隐藏了各种陷阱。多年来,我在部分旋转代码方面一直存在一个bug,比如查找最大元素、使用的代码
abs()
、错误的
fabs()
——以及启用的警告不足。直到所有的|元素|都小于1.0时,错误才真正显现出来-之后发生了0.0的div。
(1.0*DBL_EPSILON)
的意义是什么?能骑骡子吗
// Rarely the right thing to do.
#define EPSILON DBL_EPSILON
if(fabs(matrix->items[from]) < EPSILON){