从C ++中的数据库值处理-0

时间:2015-11-30 15:04:26

标签: c++ database negative-zero

目前我正在研究一些C ++代码,我需要从数据库中读取数据,如果数据库值不为零,那么我需要应用一些其他逻辑。

但是在数据库中有一些正在计算的值,可以显示为-0.0。而这个负零被视为C ++双变量中的垃圾值。我已经在构造函数中将值初始化为0.0

示例代码:

for(Sample::List<BalanceSheet>::Iterator i((Sample::List<BalanceSheet> &) Balance.Entries()); i.HaveItem(); ++i) // This list is being populated from Database
{
    if (SomeCondition != "")
    {
        if (i->GetBalance() != 0) // This is where am getting Garbage values since GetBalance() returns -0.0
            {
             DoOperation();
            }
    }
}

2 个答案:

答案 0 :(得分:2)

-0.0double的完全有效值。你遇到的问题是你正在比较不平等的双打。

你应该做的是这样的事情:

i->GetBalance() > std::numeric_limits<double>::epsilon()

答案 1 :(得分:1)

首先,您应该 从不 使用==!=浮点变量。它们本质上是无意义的操作,因为浮点类型的局限性意味着即使看似无害的值也可能无法进行相同的比较。完全有可能2 + 2不是4,至少就==来识别它。

这里真正的问题是你正在使用&#34;零&#34;的标志。如上所述,值首先可能实际上不是零,但更重要的是,使用标准比较运算符很难测试。 See this related question for some discussion.

对此最佳解决方案,如果您有权访问C ++ 11或支持它的编译器,则根据Vlad在该问题上的答案使用copysign。该功能需要2个参数。第一个表示返回值的大小,第二个表示符号。这是一个例子:

#include "iostream"
#include <math.h>

using namespace std;

int main()
{
    double posZero = +0.0d;
    double negZero = -0.0d;

    if( copysign( 1, posZero ) < 0 )
    {
        cout << "posZero is negative\n";
    }
    else
    {
        cout << "posZero is positive\n";
    }

    if( copysign( 1, negZero ) < 0 )
    {
        cout << "negZero is negative\n";
    }
    else
    {
        cout << "negZero is positive\n";
    }
}
  

posZero是积极的   negZero是否定的

在此示例中,copysign根据第二个参数上的符号创建值+/- 1。您的目的的第一个参数可以是任何非零值,但也可能是1.

或者,您可以使用signbit,这可能更直接。以上版本使用此功能:

#include "iostream"
#include <math.h>

using namespace std;

int main()
{
    double posZero = +0.0d;
    double negZero = -0.0d;

    if( signbit( posZero ) )
    {
        cout << "posZero is negative\n";
    }
    else
    {
        cout << "posZero is positive\n";
    }

    if( signbit( negZero ) )
    {
        cout << "negZero is negative\n";
    }
    else
    {
        cout << "negZero is positive\n";
    }
}

输出相同。