Hello *,
I was writing an assert() stmt when I realized the following (see code). Can anyone explain why/how. My final aim is to be able to write an assert stmt for verifying that my function (a demo function) works fine.

I heard from someone that there are special assert-macros/comparision-operators for floating point arithmatic. Is it trur?

#include <iostream>

using namespace std ;

int main()
{
    double a = 2.2, b = 1234.5678 ;
    double c = a * b ;
    //accorging to windows' calc.exe 2.2 * 1234.5678 = 2716.04916
    //which of course is correct if you multiply manually
    if( 2716.04916 == c )
        cout << "Cacl.exe and C++ give same results" << endl ;
    else
        cout << "Cacl.exe gives 2716.04916 and C++ gives "<< c << endl ;

    //so we know that assert( 2716.04916 == c ) will fail for sure.

    return 0;
}

When I run the code (compiled and run on VC 6.0) this is the output I get:
------------------------------------------------------------------
Cacl.exe gives 2716.04916 and C++ gives 2716.05
Press any key to continue
------------------------------------------------------------------

Recommended Answers

All 3 Replies

line 11 may or may not work even though it would appear to us that it should. The reason is because many floats can not be represented exactly in memory due to the way IEEE math works. The best you can do is check for a range of values instead of an exact value.

a. you should be able to get a more accurate output by using cout << fixed << setprecision(5).

b. the accuracy of the mantissa of a floating point value on a c++ implementation can be gauged from std::numeric_limits<float>::digits.
rough accuracy for reasonable small values would be within += std::numeric_limits<float>::epsilon()

Thanks guys.. Indeed the problem is due to the way a double/float value is represented in memory..

Here is a nice link I found describing how to do floating point comparisions..

Here is updated code for insight into the memory:

#include <iostream>

using namespace std ;

template< typename _T >
void print_hex( const _T* d )
{
    const unsigned char* ar = (const unsigned char*) d ;
    for( int i = 0; i < sizeof(_T); i++ )
        printf("%X ", ar[i]) ;
    putch('\n') ;
}

int main()
{
    double a = 2.2, b = 1234.5678 ;
    double c, d ;

    memset(&c, 0, sizeof(double)) ;
    memset(&d, 0, sizeof(double)) ;

    cout << "After memset, before assignment\n" ;
    print_hex(&c) ;
    print_hex(&d) ;

    c = a * b ;
    d = 2716.04916 ;

    cout << "\nAfter assignment\n" ;
    print_hex(&c) ;
    print_hex(&d) ;

    //accorging to windows' calc.exe 2.2 * 1234.5678 = 2716.04916
    //which of course is correct if you multiply manually
    if( d == c )
        cout << "Cacl.exe and C++ give same results" << endl ;
    else
        printf("\n\"operator ==\" says %f and %f are different numbers.\n\n" ,d ,c );

    return 0;
}

And here is my output with VS 6.0 on Intel.
------------------------------------------
After memset, before assignment
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

After assignment
8C E0 7F 2B 19 38 A5 40
8B E0 7F 2B 19 38 A5 40

"operator ==" says 2716.049160 and 2716.049160 are different numbers.

Press any key to continue
------------------------------------------

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.