Google
 

Tuesday, October 09, 2007

Intel IA32 Floating-Point Arithmetic problems with GCC

#include <stdio.h>
#include <stdlib.h>

double recip( int denom)
{
    return 1.0 / (double)denom;
}

void do_nothing(){}

void test1( int denom)
{
    double r1,r2;
    int t1,t2;

    r1 = recip(denom);
    r2 = recip(denom);
    t1 = r1 == r2;
    printf("test1 t1: r1 %f %c= r2 %f\n",r1,t1 ? '=' : '!',r2);
    do_nothing();
    t2 = r1 == r2;
    printf("test1 t2: r1 %f %c= r2 %f\n",r1,t2 ? '=' : '!',r2);
}

void test2(int denom)
{
    double r1;
    int t1;
    r1 = recip(denom);
    t1 = r1 == 1.0 /(double)denom;
    printf("test2 t1: r1 %f %c= 1.0/10.0 \n",r1,t1 ? '=' : '!');
}

long double recip_l(int denom)
{
    return 1.0/(long double)denom;
}

void test3(int denom)
{
    long double r1,r2;
    int t1, t2, t3;

    r1 = recip(denom);
    r2 = recip(denom);
    t1 = r1 == r2;
    printf("test3 t1: r1 %f %c= r2 %f\n",(double)r1,t1 ? '=' : '!',(double)r2);

    do_nothing();
    t2 = r1 == r2;
    printf("test3 t2: r1 %f %c= r2 %f\n",(double)r1,t2 ? '=' : '!',(double)r2);

    t3 = r1 == 1.0 /(long double)denom;
    printf("test3 t3: r1 %f %c= 1.0/10.0 \n",(double)r1,t3 ? '=' : '!');
}

int main(int argc, char* argv[])
{
    test1(10);
    test2(10);
    test3(10);
    system("PAUSE");
    return 0;
}

// Using
// Compile the code with GCC with compile parameters repectively
// a. -O2
// b. -ffloat-store

//Result running on redhat linux
//[root@localhost download]# gcc -O2 2.4.6.c
//[root@localhost download]# ./a.out
//test1 t1: r1 0.100000 != r2 0.100000
//test1 t2: r1 0.100000 == r2 0.100000
//test2 t1: r1 0.100000 == 1.0/10.0
//test3 t1: r1 0.100000 == r2 0.100000
//test3 t2: r1 0.100000 == r2 0.100000
//test3 t3: r1 0.100000 == 1.0/10.0
//sh: line 1: PAUSE: command not found
//
//
//[root@localhost download]# gcc -ffloat-store 2.4.6.c
//[ root@localhost download]# ./a.out
//test1 t1: r1 0.100000 == r2 0.100000
//test1 t2: r1 0.100000 == r2 0.100000
//test2 t1: r1 0.100000 != 1.0/10.0
//test3 t1: r1 0.100000 == r2 0.100000
//test3 t2: r1 0.100000 == r2 0.100000
//test3 t3: r1 0.100000 == 1.0/10.0
//sh: line 1: PAUSE: command not found



--
Happy day, happy life!

No comments: