IBM Support

IV91686: UNEXPECTED ISTRINGSTREAM SETPRECISION FLOAT VALUE ROUNDING

Subscribe

You can track all active APARs for this component.

APAR status

  • Closed as program error.

Error description

  • When storing a floating point value to an ostringstream object
    and retrieving it in an istringstream object, the resulting
    value has unexpected rounding compared to the setprecision()
    setting.
    
    
    
       === TEST CASE ===
    
    #include <iomanip>
    #include <iostream>
    #include <sstream>
    
    using namespace std;
    
    int main(int argc, char **argv)
    {
        float value      = 0.00342999981f;
        float checkValue = 0;
    
        cout.precision(17);
        cout << "original value:                                "
           << value << endl;
    
        ostringstream outstream_test;
        outstream_test << value;
        cout << "ostringstream string with no setprecision(9):  "
           << outstream_test.str().c_str() << endl;
    
        ostringstream outstream;
        outstream << std::setprecision(9) << value;
        cout << "ostringstream string after setprecision(9):    "
           << outstream.str().c_str() << endl;
    
        istringstream instream(outstream.str());
        instream >> std::setprecision(9) >> checkValue;
        cout << "instream string-to-float conversion:           "
           << checkValue << endl;
    
        if (value != checkValue)
           cout << "FAIL - Value does not match convert:" << endl;
        else
           cout << "PASS - Value matches convert:" << endl;
    
        cout << setw(55) << hex << *(unsigned int *)(&value) <<endl;
        cout << setw(55) << hex << *(unsigned int *)(&checkValue)
           << endl;
    
        return 0;
    }
    
    
    $ xlC test.cpp; ./a.out
    original value:                           0.0034299998078495264
    ostringstream string with no setprecision(9):
                                              0.00343
    ostringstream string after setprecision(9):
                                              0.00342999981
    instream string-to-float conversion:
                                              0.0034300000406801701
    FAIL - Value does not match convert:
                                              3b60c9d9
                                              3b60c9da
    $
    

Local fix

Problem summary

  • PROBLEM DESCRIPTION:
    When converting an istringstream floating point string in the
    form of 0.<<two or more 0's>><<digits>> to binary, the XL C++
    Runtime changes the string to 0.0<<digits>> and calls strtof()
    with that string to convert to binary.  It then divides the
    result by 10 * <<number of 0's removed>>.  The extra rounding
    of the division operation results in precision loss.
    
    USERS AFFECTED:
    Users using an istringstream object containing floating point
    strings in the form of 0.<<two or more 0's>><<digits>>, e.g.,
    0.00342999981, and assigning the value to a 'float' variable.
    

Problem conclusion

  • The runtime should not remove 0's from the string before
    conversion and then perform the division afterwards which
    results in precision loss.  The issue has been fixed.
    

Temporary fix

Comments

APAR Information

  • APAR number

    IV91686

  • Reported component name

    XL C FOR AIX

  • Reported component ID

    5725C7100

  • Reported release

    D13

  • Status

    CLOSED PER

  • PE

    NoPE

  • HIPER

    NoHIPER

  • Special Attention

    NoSpecatt / Xsystem

  • Submitted date

    2016-12-21

  • Closed date

    2016-12-21

  • Last modified date

    2016-12-21

  • APAR is sysrouted FROM one or more of the following:

    IV90071

  • APAR is sysrouted TO one or more of the following:

Fix information

  • Fixed component name

    XL C FOR AIX

  • Fixed component ID

    5725C7100

Applicable component levels



Document information

More support for: XL C for AIX
Compiler

Software version: D13

Reference #: IV91686

Modified date: 21 December 2016