【问题标题】:Can double's overflow to negative values?双倍的溢出到负值吗?
【发布时间】:2013-02-19 15:45:32
【问题描述】:

您好,我正在使用 g++ 编译器,并且我正在经历(我认为)双打下溢,这可能吗?如果可以,行为是如何定义的

我在这里上传了协方差矩阵(51x51)的csv格式:http://pastebin.com/r0fx1qsx

这是我用来计算行列式的代码(在 c++ 中需要 boost)(我已经切换到 long doubles 并且没有效果):

int determinant_sign(const boost::numeric::ublas::permutation_matrix<std ::size_t>& pm)
{
    int pm_sign=1;
    std::size_t size = pm.size();
    for (std::size_t i = 0; i < size; ++i)
        if (i != pm(i))
            pm_sign *= -1.0; // swap_rows would swap a pair of rows here, so we change sign
    return pm_sign;
}

long double determinant( boost::numeric::ublas::matrix<long double>& m ) {
    boost::numeric::ublas::permutation_matrix<std ::size_t> pm(m.size1());
    long double det = 1.0;

    if( boost::numeric::ublas::lu_factorize(m,pm) ) {
        det = 0.0;
    } else {
        for(int i = 0; i < (int)m.size1(); i++)
            det *= m(i,i); // multiply by elements on diagonal
        det = det * determinant_sign( pm );
    }
    return det;
}

我得到的数据结果是-3.59916e-183

当我运行以下matlab 代码时:

M = csvread('path/to/csv');
det(M)
the result I get is:

4.2014e-173

如您所见,一个是(稍微)正面,一个是(稍微)负面

【问题讨论】:

  • 你能给我们看看代码吗?
  • 好吧,我正在计算一个数字非常小的大矩阵的行列式。在 matlab 中完成后,我得到了很大的结果(~e128),但在 c++ 中使用双打我得到了负面结果
  • 请显示代码,添加到双精度永远不会使其变小,所以你必须做其他事情。
  • 这个数字太小了,可能只是零,有一些计算错误!
  • 您是否尝试使用 mpfr 提供的数字类型和较大的精度来计算它?用 Eigen 计算它,尝试几种可用的算法?对我来说,这听起来像是一个简单的数值稳定性问题。

标签: c++ double ieee-754 underflow boost-ublas


【解决方案1】:

假设浮点单元运行正确,它不会溢出到负值 - 如果值超出有效范围,结果将是“+INF”(正无穷大)。这只会发生在有符号整数上。

当然,当预期得到肯定答案时,在给出否定答案的计算中完全有可能出现各种错误。

【讨论】:

  • 技术上不应该是 +HUGE_VAL,可能是 +INFINITY 或 +DBL_MAX,这取决于目标构建环境支持的浮点标准吗?
  • 我使用了 +INF 的 IEEE 值,这是最常见的浮点格式。但是,是的,我确信某些 C/C++ 头文件中有一个常量。我不完全确定这是否会对答案的含义产生重大影响。
  • 这并不是说您永远不会从浮点计算中得到意外的负值 (exploringbinary.com/…)
  • 是的,这就是我想说的“计算中的各种错误当然完全有可能......” [在链接中给出的示例中,这是“故意的”,但是这主要是由于 0.1 不能精确地表示为二进制数,所以乘以 0.1 的结果会稍微偏离,当你开始使用非常大的数字时,舍入效应会导致结果消极。
  • @Mats Petersson 我不知道我第一次怎么看错了那句话,但是是的,我基本上只是重复了你说的话:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多