Shane
Shane

Reputation: 2375

Why do these two code snippets produce different results? (Float, Double precision)

I am only beginning to learn C++ and have been messing around with float and double values. Below are two code snippets that seem to me to be doing the same thing but give different results. What am I missing? Can someone explain the precision error the first code must have to get a different result than the second.

int _tmain(int argc, _TCHAR* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int counter = 0;

    for(counter; ((double)counter * f - (double)counter * d) < 0.34; counter++) {}

    cout << "Iterations = " << counter << "\n" ;

    system("pause");
    return 0;
}


int main (int argc, const char * argv[])
{
    float time_f = 0.1;    
    double time_d = 0.1;
    float total_f = 0;
    double total_d = 0;
    int count=0;
    double difference = 0;
    while (true) {
        total_d = count * time_d;
        total_f = count * time_f;
        if(total_f - total_d >= 0.34){

            break;
        }
        count++;

    }
    std::cout <<  count << "\n";
    system("pause");
}

I have altered the cast of my for loop condition between float and double but the value does not differ.

Upvotes: 0

Views: 308

Answers (3)

LihO
LihO

Reputation: 42085

Difference between that two code snippets is in cast. counter * f is casted to double in first snippet and stored to float variable in second one.

Here's an example of how it could look like:

#include <stdio.h>

int main(int argc, char* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int count = 0;

    for(count; (double)(count * f) - (double)(count * d) < 0.34; count++);

    printf("Iterations = %d\n", count);
    count = 0;

    while (true)
    {
        double total_d = count * d; // is equal to (double)(count * d)
        double total_f = count * f; // is equal to (double)(count * f)
        if (total_f - total_d >= 0.34)
            break;
        count++;
    }
    printf("Iterations = %d\n", count);

    return 0;
}

Upvotes: 1

Thund
Thund

Reputation: 13

You haven't casted count to double here:

total_d = count * time_d;
total_f = count * time_f;

Another thing, those loops will never end since both subtraction operands have the same value :S

Upvotes: 0

James Kanze
James Kanze

Reputation: 153889

Both float and double have a finite representation, which means they take on a series of descrete values, and not just any real value. In particular, in your example, 0.1 has no exact floating point representation on any modern machine I know of (all of which use a base which is a power of 2 in their implementation—0.1 is 1/5 * 1/2, and nothing which is a multiple of 1/5 can have a finite representation unless the base is a multiple of 5).

The result is that either float and double have the same underlying representation (not usually the case), or there will be a difference as soon as count is different from 0.

The usual reference for this subject is “What Every Computer Scientist Should Know About Floating-Point Arithmetic”. Until you've read and understood (or at least understood the implications) it, you shouldn't touch machine floating point.

Upvotes: 2

Related Questions