65.9K
CodeProject is changing. Read more.
Home

A Generalized Rounding Method for Floating-Point Numbers

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1 vote)

Jun 12, 2011

CPOL
viewsIcon

12381

A C# method which rounds to the nearest multiple of a chosen power of an arbitrary base.

//  RoundXtoNearestIthPowerOfR
//
// For r greater than 1 and I less than 0, this function rounds the
// fractional portion of a value to the nearest multiple of the
// Ith power of r.  Thus, the sequence in the example here arises,
// where c = RoundXtoNearestIthPowerOfR(x,2,-2):
//
//   x  0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1.0  1.1
//   c  0.0  0.0  0.25 0.25 0.5  0.5  0.5  0.75 0.75 1.0  1.0  1.0
//
// The concept of exponentiation of non-integer negative r to negative
// fractional powers of I is not supported.  The absolute value of r is
// used as the base of exponentiation, although any values of x, r, and
// I can be supplied as arguments to this function.  Zero is returned
// if a value r=0 is supplied.
// 
// Cases may arise in multiple computations where you may want to round
// values consistently to some decimal fraction or multiple thereof
// which is not a pure binary fraction; and this function directly
// provides that capability.  It is thus possible to partition error
// (if you have a benchmark function to provide checkpoint values)
// into small neighborhoods rather than allowing it to directly
// propagate into successive calculations.  This can be important
// when using a recursion formula or a truncated series expansion.
//
// PARAMETER "x" -  Value to be rounded
// PARAMETER "r" -  Base of rounded value
// PARAMETER "i" -  Exponent of base for rounding
//
public double RoundXtoNearestIthPowerOfR(double x, double r, double i)
{
  double res=0; r = Math.Abs(r);
  if (r > 0)
  {
    double rr = x*Math.Pow(r, -i); double flrr = Math.Truncate(rr);
    res = Math.Pow(r, i)*(flrr-Math.Truncate(2*flrr - 2*rr));
  }
  return res;
}