This discussion is archived
3 Replies Latest reply: Feb 2, 2012 9:06 PM by 858326 RSS

Abnormal behaviour of float.

858326 Newbie
Currently Being Moderated
Hi All,

I have different output when trying to cast float/double to integer.

I know that doing such a conversion is illegal, but the (legacy) code is written like that, and now we are trying to make the code compliant with C+ standards.+

test.cc
#include<iostream>
using namespace std;

int main()
{
    float f = 0.9972222;
    short fx = (f*1440);
    cout << "Using float\t - " << fx << endl;
    double d =  0.99722222222222;
    short dx = (d*1440);
    cout << "Using double\t - " << dx << endl;

    return 0;
}
The environment details and the output.
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.4 (Tikanga)

$ uname -a
Linux n320.ibsplc.com 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

# compile with CC
$ CC -m32 -g -o test test.cc
$ ./test
Using float      - 1436
Using double     - 1435

# compile with g++
$ g++ -Wall -m32 -g -o test test.cc
test.cc: In function ‘int main()’:
test.cc:7: warning: converting to ‘short int’ from ‘float’
test.cc:10: warning: converting to ‘short int’ from ‘double’
$ ./test
Using float      - 1435
Using double     - 1435
I am getting different values when we trying to use float and double with CC whereas the values are same with g++

i also compared the output of different numbers (up-to 4 digit precision).

When using double the output is same in both CC and g++.
When using float, for some cases (like the one mentioned above) CC gives one value more ( float : 1436...double : 1435 ) whereas g++ gives same value ( float : 1435...double : 1435 )

Can anyone explain why this happens with CC ?

Any inputs would be of great help.


Thanks & Regards,
Sreekar.

Edited by: 855323 on Feb 2, 2012 8:54 PM
  • 1. Re: Abnormal behaviour of float.
    Darryl Gove Newbie
    Currently Being Moderated
    Its to do with promotion to double. Here's what I think is happening:

    0.9972222 * 1440 =1435.99968
    A single precision variable can hold about 7 digits so the multiply does a rounding at the '6' digit, and this makes the result 1436.

    If the whole calculation is done as a double precision value, then you end up with many more digits of precision.

    When the code converts to int, it truncates at the decimal point. So 1435.9 becomes 1435.

    So gcc is doing the computation as double precision even though it is a single precision calculation, studio is doing it as specified.

    So the question is which is the desired answer?

    If you want to make it consistent, I'd suggest adding (double) to force the computation to be evaluated as a double precision:
    short fx = ((double)f*1440);

    On the other hand you might want to round the values to the nearest int rather than truncate them:
    short fx = (f*1440+0.5);
    [Although there might be some values which round up for float and down for double... you'd need a numeric analysis to figure that out.]

    Regards,

    Darryl.
  • 2. Re: Abnormal behaviour of float.
    Darryl Gove Newbie
    Currently Being Moderated
    g++ gives the same behaviour as studio:

    #include<stdio.h>

    int main()
    {
    float f = 0.9972222;
    short fx = (f*1440);
    printf("Using float %i %20.18f\n",fx,(float)(f*1440));
    double d = 0.99722222222222;
    short dx = (d*1440);
    printf("Using double %i %20.18f\n",dx,(double)(d*1440));

    return 0;
    }

    $ g++ -v
    Using built-in specs.
    Target: sparc-sun-solaris2.10
    Configured with: ../gcc-4.3.2-src/configure prefix=/pkg/gnu enable-languages=c++,fortran with-cpu=ultrasparc enable-threads=posix enable-shared with-gmp=/pkg/gnu --program-suffix=-4.3.2-5.10
    Thread model: posix
    gcc version 4.3.2 (GCC)

    $ g++ t1.c
    ./a.out
    Using float 1436 1436.000000000000000000
    Using double 1435 1435.999999999996816769

    $ CC t1.c
    $ ./a.out
    Using float 1436 1436.000000000000000000
    Using double 1435 1435.999999999996816769

    Regards,

    Darryl.
  • 3. Re: Abnormal behaviour of float.
    858326 Newbie
    Currently Being Moderated
    Hi Darryl,

    Thank you for your inputs.

    We are using -m32 in the compilation.
    # without -m32 flag
    $ g++ -Wall -g -o test test.cc
    test.cc: In function ‘int main()’:
    test.cc:8: warning: converting to ‘short int’ from ‘float’
    test.cc:11: warning: converting to ‘short int’ from ‘double’
    $ ./test
    Using float      - 1436
    Using double     - 1435
    
    # with -m32 flag
    $ g++ -m32 -Wall -g -o test test.cc
    test.cc: In function ‘int main()’:
    test.cc:8: warning: converting to ‘short int’ from ‘float’
    test.cc:11: warning: converting to ‘short int’ from ‘double’
    $ ./test
    Using float      - 1435
    Using double     - 1435
    Without that the values obtained with both CC and g++ are same.

    I think its time to chase the analysts to know what value they need as per the business.


    Thanks & Best Regards,
    Sreekar

    Edited by: 855323 on Feb 2, 2012 9:06 PM

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points