Обработчик -0 из значения базы данных в переполнении стека

В настоящее время я работаю над кодом 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();
}
}
}

0

Решение

-0.0 совершенно допустимое значение для double, Проблема в том, что вы сравниваете двойные числа по неравенству.

Что вы должны сделать, это что-то вроде этого:

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

Другие решения

Во-первых, вы должны никогда использовать == или же != с переменными с плавающей точкой. По сути, это бессмысленные операции, поскольку ограничения типов с плавающей запятой означают, что даже, казалось бы, безобидные значения могут не сравниваться одинаково. Вполне возможно, что 2 + 2 не 4, по крайней мере, насколько == определил бы это.

Настоящая проблема здесь заключается в том, что вы используете знак «нулевого» значения, которое, как указано выше, в действительности не может быть точно нулевым, во-первых, но, что более важно, его сложно проверить с помощью стандартных операторов сравнения. Смотрите этот связанный вопрос для некоторого обсуждения.

Лучшее решение для этого, если у вас есть доступ к C ++ 11 или поддерживающему его компилятору, это использовать 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";
}
}

С таким же выходом.

1

По вопросам рекламы [email protected]