healingtao
asked on
rounding question
I'm currently using microsoft visual c++ .net version 7.1.3088
I need to round a double value.
I tried the following code
stringstream ssConvert("");
// initially I retrieve the value from my class where it's a string
string tempStr = m_ColumnData.at(i);
double dblValue = atof(tempStr.c_str());
// now I try use Math rounding function
dblValue = Math::Round(dblValue, 2); // I need to round to 2 decimal places
ssConvert.precision(2);
ssConvert << dblValue;
m_ColumnData[i] = ssConvert;
When I compile, I get error C2653: 'Math' : is not a class or namespace name
I tried to
#include <cmath> or math.h and I'm getting the same compiler error.
Thanks in advance
I need to round a double value.
I tried the following code
stringstream ssConvert("");
// initially I retrieve the value from my class where it's a string
string tempStr = m_ColumnData.at(i);
double dblValue = atof(tempStr.c_str());
// now I try use Math rounding function
dblValue = Math::Round(dblValue, 2); // I need to round to 2 decimal places
ssConvert.precision(2);
ssConvert << dblValue;
m_ColumnData[i] = ssConvert;
When I compile, I get error C2653: 'Math' : is not a class or namespace name
I tried to
#include <cmath> or math.h and I'm getting the same compiler error.
Thanks in advance
You could also round it arithmetically:
dblValue = ( (int)((dblValue + 0.005f) * 100.0f) ) /100.0f;
as long as your original number *100 doesn't exceed a 32 bit integer.
Because of the internal representation of floating numbers, though, you might wind with
x.499999999999999999 instead of x.50000000000000, which puts you right back where you started from... you'll have to try it and see it if works for your range of values.
dblValue = ( (int)((dblValue + 0.005f) * 100.0f) ) /100.0f;
as long as your original number *100 doesn't exceed a 32 bit integer.
Because of the internal representation of floating numbers, though, you might wind with
x.499999999999999999 instead of x.50000000000000, which puts you right back where you started from... you'll have to try it and see it if works for your range of values.
Have you tried adding the math.h header file to your code? That might work, but not sure. Math::Round(double, int) basically means that the first parameter (double) can be a number like 2.34785647 and the second parameter (int) tells how many decimal places to round off to. So Math::Round(2.34785647, 1) would return 2.3 Hope that this helps.
or this way:
void round( double &dblVal )
{
double dblTemp = floor( dblVal * 100.0f );
dblVal *= 100.0;
if( dblVal - dblTemp >= 0.5 ) dblVal = dblTemp + 1.0;
else dblVal = dblTemp;
dblVal /= 100.0;
}
good luck ;)
ikework
void round( double &dblVal )
{
double dblTemp = floor( dblVal * 100.0f );
dblVal *= 100.0;
if( dblVal - dblTemp >= 0.5 ) dblVal = dblTemp + 1.0;
else dblVal = dblTemp;
dblVal /= 100.0;
}
good luck ;)
ikework
This will handle all double's and you can spesify the number of digits.
double Round(double Value, int Precision)
{
static const double Base = 10.0f;
double Complete5, Complete5i;
Complete5 = Value * pow(Base, (double) (Precision + 1));
if(Value < 0.0f)
Complete5 -= 5.0f;
else
Complete5 += 5.0f;
Complete5 /= Base;
modf(Complete5, &Complete5i);
return Complete5i / pow(Base, (double) Precision);
}
double Round(double Value, int Precision)
{
static const double Base = 10.0f;
double Complete5, Complete5i;
Complete5 = Value * pow(Base, (double) (Precision + 1));
if(Value < 0.0f)
Complete5 -= 5.0f;
else
Complete5 += 5.0f;
Complete5 /= Base;
modf(Complete5, &Complete5i);
return Complete5i / pow(Base, (double) Precision);
}
@pb_india: the standard-c-header math.h doesn't have any class Math, it's a c-header... no classes,
the c++-standard-header cmath doesn't have it as well,
i guess it's a microsoft-class as wayside said above....
the c++-standard-header cmath doesn't have it as well,
i guess it's a microsoft-class as wayside said above....
ASKER
pb_india ,
I like the code you provided but I have a slight problem with it.
Here is the sample I'm using to test this
#include "stdafx.h"
#include <math.h>
#include <sstream>
#include <fstream>
#include <string>
double roundVal(double Value, int Precision);
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double dblValue;
stringstream ssConvert("");
string tempStr = "12343.234233445";
dblValue = atof(tempStr.c_str());
dblValue = roundVal(dblValue, 6);
ssConvert.precision(6);
ssConvert << dblValue;
string finalVal = ssConvert.str();
return 0;
}
double roundVal(double Value, int Precision)
{
static const double Base = 10.0f;
double Complete5, Complete5i;
Complete5 = Value * pow(Base, (double) (Precision + 1));
if(Value < 0.0f)
Complete5 -= 5.0f;
else
Complete5 += 5.0f;
Complete5 /= Base;
modf(Complete5, &Complete5i);
return Complete5i / pow(Base, (double) Precision);
}
When I use precision 6 in this case my finalVal is 12343.2 but I need 12343.234233
When I increase precision say to 20 I thought that it'll fix the problem but I get "12343.234233445". I thought precision only counts decimals but apparently it's the whole number. I need something generic because I have a lot of big values with up to 9 decimal places.
Does it make sense to take count the real number part (in this case 5) and add number of decimals(in this case 6) , add them and set precision(11) ???
Or is there an easier way?
Thanks
I like the code you provided but I have a slight problem with it.
Here is the sample I'm using to test this
#include "stdafx.h"
#include <math.h>
#include <sstream>
#include <fstream>
#include <string>
double roundVal(double Value, int Precision);
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double dblValue;
stringstream ssConvert("");
string tempStr = "12343.234233445";
dblValue = atof(tempStr.c_str());
dblValue = roundVal(dblValue, 6);
ssConvert.precision(6);
ssConvert << dblValue;
string finalVal = ssConvert.str();
return 0;
}
double roundVal(double Value, int Precision)
{
static const double Base = 10.0f;
double Complete5, Complete5i;
Complete5 = Value * pow(Base, (double) (Precision + 1));
if(Value < 0.0f)
Complete5 -= 5.0f;
else
Complete5 += 5.0f;
Complete5 /= Base;
modf(Complete5, &Complete5i);
return Complete5i / pow(Base, (double) Precision);
}
When I use precision 6 in this case my finalVal is 12343.2 but I need 12343.234233
When I increase precision say to 20 I thought that it'll fix the problem but I get "12343.234233445". I thought precision only counts decimals but apparently it's the whole number. I need something generic because I have a lot of big values with up to 9 decimal places.
Does it make sense to take count the real number part (in this case 5) and add number of decimals(in this case 6) , add them and set precision(11) ???
Or is there an easier way?
Thanks
healingtao ,
Problem is in your code. The function I provided is fine.
Preision 1 would round it to 1 after decimal
Precision 2 will round it to 2 digits after decimal
See below: The commments on cout
double dblValue=0;
stringstream ssConvert("");
dblValue = 123.43234233445;//atof(tem pStr.c_str ());
cout<<dblValue<<endl; // [RESULTis 123.432...this is before the function is used]
dblValue = roundVal(dblValue,2);
cout<<dblValue;// [RESULT is 123.4 /...after the rounding is done to 1 ]
ssConvert.precision(6);
ssConvert << dblValue;
string finalVal = ssConvert.str();
Problem is in your code. The function I provided is fine.
Preision 1 would round it to 1 after decimal
Precision 2 will round it to 2 digits after decimal
See below: The commments on cout
double dblValue=0;
stringstream ssConvert("");
dblValue = 123.43234233445;//atof(tem
cout<<dblValue<<endl; // [RESULTis 123.432...this is before the function is used]
dblValue = roundVal(dblValue,2);
cout<<dblValue;// [RESULT is 123.4 /...after the rounding is done to 1 ]
ssConvert.precision(6);
ssConvert << dblValue;
string finalVal = ssConvert.str();
Correction, pb_india.
Check out http://www.cplusplus.com/ref/iostream/ios_base/precision.html
Specifically:
The precision determines the maximum number of digits that shall be output on insertion operations to express floating-point values, counting both the digits before and after the decimal point.
Check out http://www.cplusplus.com/ref/iostream/ios_base/precision.html
Specifically:
The precision determines the maximum number of digits that shall be output on insertion operations to express floating-point values, counting both the digits before and after the decimal point.
So, Author, if you want to get X digits of precision following decimal:
outstream.precision((int)( log10(dblV alue))+1+X )
Or in your case,
ssConvert.precision((int)( log10(dblV alue))+7); // For max 6 digits after decimal
outstream.precision((int)(
Or in your case,
ssConvert.precision((int)(
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
wayside,
Thanks, exactly what I was looking for. Excellent, simple solution that is working great for all cases.
Thanks, exactly what I was looking for. Excellent, simple solution that is working great for all cases.
For regular C++, one way would be to add 0.005 to the number before putting it to the stringstream.
ssConvert << (dblValue + 0.005f);