Hi,

I have a problem that happens very rarely. I have a calculation which ads (for example) -15000.00 to 15575.51 and saves the results to an oracle database. However, the reslut in the databse is 575.51000002

Both figures are loaded elsewhere from the database and either have 0 or 2 decimals as in the example above.

The code processes millions of transactions, but less than .01 % has this error. Any ideas?

Thanks,
Shawn

AddUpInputAK(
int iIndexInputAK,
int iAccumPos,
int iAccumNeg,
double* naSumsBW,
double* naSumsRW )
{
[INDENT]int iRet = SQC_C_Success;
int iIndexSum;
double nBetragBook;
double nBetragBest;
double nBetragKto;
double nBetragRef;
int iAK_Vorz;
 
////
// 
////
if ( ALG_IsIntNull( iIndexInputAK ) ) {
[INDENT]goto L_Eof;
[/INDENT]}
if ( ALG_IsIntNull( iAccumPos ) && ALG_IsIntNull( iAccumNeg ) ) {
[INDENT]goto L_Eof;
[/INDENT]}
iIndexSum = 0;
nBetragBook = m_naInpAbrKompBetrag[iIndexInputAK];
if ( ALG_IsDoubleNull( nBetragBook ) ) {
[INDENT]goto L_Eof;
[/INDENT]}
////
// Correct signage
////
iAK_Vorz = 1;
if ( m_saInpAbrKompVorz[iIndexInputAK].Left( 1 ) == "-" ) {
[INDENT]iAK_Vorz = -1;
nBetragBook = nBetragBook * ( -1.0);
[/INDENT]}
 
if ( m_sPosArt == "KTO" ) {
////
// Accounts
////
if ( m_sKtoWhg == m_saInpAbrKompWhg[iIndexInputAK] ) {
[INDENT]nBetragKto = m_naInpAbrKompBetrag[iIndexInputAK];
[/INDENT]if ( iAK_Vorz < 0 ) {
[INDENT]nBetragKto = nBetragKto * ( -1 );
[/INDENT]} else {
[INDENT]nBetragKto = nBetragBook;
[/INDENT]}
 
ALG_SetDoubleNull( &nBetragKto );
 
 
}
if ( ! ALG_IsDoubleNull( nBetragKto ) ) {
[INDENT]naSumsBW[iIndexSum] = naSumsBW[iIndexSum] + nBetragKto;
[/INDENT]}
}
L_Eof:
return( iRet );
}
[/INDENT]

I'd guess that it's due to how floating point values are stored imprecisely in memory, causing the weird results to come up on rare occasions.

>The code processes millions of transactions, but less than .01 % has this error. Any ideas?
That's a typical floating-point rounding fudge. If it's a serious enough problem, you can try to use a more precise type such as long double, or remove floating-point altogether to maintain exact precision. Though I suspect that an imprecision at the eighth decimal place isn't that much of an issue unless you're trying to do something with vanilla C++ types that shouldn't be done with vanilla C++ types. If that's the case, you really need to get a high precision mathematics library.

Hi, thanks for all the replies.

The problem arises later on when external systems want to do a reconciliiation and then fails. This external system uses a language which generally does not have such problems and as such it hasn't been programmed to handle such differences.

Thanks again

Shawn

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.