c++ - Doubles rounding again -
in program there precisions (some positive integer, in cases supposed of form ) doubles, double * precision
should become integer.
but know floating point numbers inaccurate, so, example 1.3029515
saved 1.3029514999999998...
, , in program need write such floating point number file, want 1.3029515
written instead of 1.3029514999999998...
.
previously precision of form used in program, , i've reached wanted result piece of code below:
// have function doubles equality check inline bool samedoubles(const double& lhs, const double& rhs, const double& epsilon) { return fabs(lhs - rhs) < epsilon; } inline void rounddowndouble(double& value, const unsigned int& numberofdigitsinfraction = 6) { assert(numberofdigitsinfraction <= 9); double factor = pow(10.0, numberofdigitsinfraction); double oldvalue = value; value = (((int)(value * factor)) / factor); // when, example, 1.45 stored 1.4499999999..., can wrong value, so, need check below double diff = pow(10.0, 0.0 - numberofdigitsinfraction); if(samedoubles(diff, fabs(oldvalue - value), 1e-9)) { value += diff; } };
but now, can't reach wanted results same technique, i've tried function below, have not succeeded:
// calculates logarithm of number given base double inline lognbase(double number, double base) { return log(number)/log(base); } // samedoubles function same in above case inline void rounddowndouble(double& value, unsigned int precision = 1e+6) { if(samedoubles(value, 0.0)) { value = 0; return; } double oldvalue = value; value = ((long int)(value * precision) / (double)precision); // when, example, 1.45 stored 1.4499999999..., can wrong value, so, need check below int pwr = (int)(lognbase((double)precision, 10.0)); long int coeff = precision / pow(10, pwr); double diff = coeff * pow(10, -pwr); if(samedoubles(diff, fabs(oldvalue - value), diff / 10.0)) { if(value > 0.0) { value += diff; } else { value -= diff; } } }
for 1.3029515
value , precision = 2000000
function returns incorrect 1.302951
value (expression (long int)(value * precision)
becomes equal 2605902
instead of 2605903
).
how can fix this? or maybe there smart way make rounding happen correctly?
you're doing rounding hard way. easy way instead:
double rounding = 0.5; if (value < 0.0) rounding = -0.5; value = ((long int)(value * precision + rounding) / (double)precision);
now there's no need rest of code.
Comments
Post a Comment