We're a community of 1076K IT Pros here for help, advice, solutions, professional growth and fun. Join us!
1,075,557 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Start New Discussion Reply to this Discussion

Floating point multiplication, precision issues

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
------------------------------------------------------------------

3
Contributors
3
Replies
1 Day
Discussion Span
6 Years Ago
Last Updated
5
Views
Question
Answered
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75
Skill Endorsements: 0

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.

Ancient Dragon
Achieved Level 70
Team Colleague
32,104 posts since Aug 2005
Reputation Points: 5,836
Solved Threads: 2,574
Skill Endorsements: 68

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()

vijayan121
Posting Virtuoso
1,740 posts since Dec 2006
Reputation Points: 1,236
Solved Threads: 320
Skill Endorsements: 11

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
------------------------------------------

thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75
Skill Endorsements: 0
Question Answered as of 2 Years Ago by Ancient Dragon and vijayan121

This question has already been solved: Start a new discussion instead

Post: Markdown Syntax: Formatting Help
 
You
 
© 2013 DaniWeb® LLC
Page rendered in 0.0641 seconds using 2.74MB