0

I have a template function based on istringstream and I've discovered that a string value of "99999.99" rounds up to 100000. In fact, I've found that the C++ iostreams in general are doing the rounding. Plain 'ole standard C printf() handles the job well. Is there any solution to this at all.

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <unistd.h>
#include <algorithm>

using namespace std;


template <class T> bool from_string(T& t, const string& s, ios_base& (*f)(ios_base&))
{
    istringstream iss(s);
    return !(iss >> f >> t).fail();
}


class MyApp {
private :
public :
    MyApp();
    virtual ~MyApp();

    void run();

    operator bool() const { return true; }
};


MyApp::MyApp()
{
}

MyApp::~MyApp()
{
}

void MyApp::run()
{
    string elementData = "99999.99";
    double fproductUnitPrice = 0.0;
    double myval = 99999.99;
    double myval2 = 99999.95;
    float myval3 = 99999.99;

    from_string<double>(fproductUnitPrice, elementData, std::dec);
    cout <<  "fproductUnitPrice=" << fproductUnitPrice << endl;
    fproductUnitPrice -= 0.05;
    cout <<  "fproductUnitPrice=" << fproductUnitPrice << endl;
    cout <<  "myval=" << myval << endl;
    cout <<  "myval2=" << myval2 << endl;
    cout <<  "myval3=" << myval3 << endl;
    printf("myval %lf\n", myval);
    printf("myval2 %lf\n", myval2);
    printf("myval3 %lf\n", myval3);
}

int main(int argc, char* argv[])
{
    MyApp myApp;

    myApp.run();
}

EDIT - The point about using float/doubles is understood, but no one has run the code I posted. The printf()s print the values correctly (with the exception of 9999.9999 which is a float). I'm more about why the discrepancy in the stdc library vs C++.

fproductUnitPrice=100000 
fproductUnitPrice=99999.9
myval=100000             
myval2=99999.9           
myval3=10000             
myval4=10000             
myval 99999.990000       
myval2 99999.950000      
myval3 10000.000000      
myval4 9999.999900       
jmarkmurphy
  • 11,030
  • 31
  • 59
Kelly Beard
  • 684
  • 1
  • 8
  • 20
  • 2
    Do **not** use floating point types for money. Store the number of cents as an integer so you get exact math and `value / 100` will give you the dollar part and `value % 100` will give you the change part. – NathanOliver Dec 03 '18 at 20:03
  • https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Jesper Juhl Dec 03 '18 at 20:05
  • Assume this isn't about money. Substitute 99999.999 or 99999.9999, because I have to deal with those values too. – Kelly Beard Dec 03 '18 at 20:12
  • @KellyBeard Please see the link I gave you. – Jesper Juhl Dec 03 '18 at 20:13
  • 2
    The same advice still applies. You want fixed point math so you don't have rounding errors. Decide how many places of precision you want and then emulate that with a integer type. Otherwise see [this](https://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout) – NathanOliver Dec 03 '18 at 20:14

0 Answers0