Round Number - page 2

 
He got what he wants and possibly even more, and is probably wandering now what that SringSubstr was in his own code :)
 

Thanks all for help me,

I using code of Thirteen. It can round a number 1.23455 to 1.2345 ( 4 digits) and 1.23456 to 1.2346

double RoundNumber(double number, int digits) {
   number = MathFloor((number * MathPow(10, digits)) + 0.4);
   return (number * MathPow(10, -digits));
}
 

Cool, just for good measure using everyone's favourite function NormalizeDouble...


// round 0.00005 down (+ve numbers)
double round4(double number)
{
   return (NormalizeDouble(number - 0.00001,4));
}

OR

// round 5 down
double round(double number,int digits)
{
   int d = 1;
   for(int i = 0 ; i <= digits ; i++) d *= 10;
   return (NormalizeDouble(number - 1.0/d,digits));
}
 

I know this is an old post, I'm just adding the function I wrote to perform bankers rounding the same way that Math.Round in C# does it in case someone stumbles across this post looking for the same info I was. The code above didn't produce the same results as Math.Round, so I wrote one of my own :-)

 MQL code:

double RoundNumber(double dNumber, int nDigits)
{
   // Use bankers rounding - if the numbers after nDigits = 5, Round up when the number before it is odd, round down when it's even
   double dRet = dNumber;
   double dInt = (int)(dNumber * MathPow(10, nDigits));
   double dRemainder = NormalizeDouble((dNumber * MathPow(10, nDigits)) - dInt, nDigits);

   if (dRemainder == 0.5)
   {
       if (MathMod(dInt, 2) != 0)      // Means the number is odd
           dRet = (dInt + 1) * MathPow(10, -nDigits);
       else
           dRet = dInt * MathPow(10, -nDigits);
   }
   else
       dRet = NormalizeDouble(dNumber, nDigits);


   return (dRet);
}

 

And if you want to validate it in CSharp

private void button1_Click(object sender, EventArgs e)
        {
            double dNumber = Convert.ToDouble(edtNumber.Text);
            int nDigits = Convert.ToInt32(edtDigits.Text);

            edtNormalizeDouble.Text = Math.Round(dNumber, nDigits, MidpointRounding.AwayFromZero).ToString();
            edtMathRound.Text = Math.Round(dNumber, nDigits).ToString();
            edtRoundNumber.Text = RoundNumber(dNumber, nDigits).ToString();
        }

        private double RoundNumber(double dNumber, int nDigits)
        {
            double dRet = dNumber;
            double dInt = (int)(dNumber * Math.Pow(10, nDigits));
            double dRemainder = Math.Round((dNumber * Math.Pow(10, nDigits)) - dInt, nDigits, MidpointRounding.AwayFromZero);
            
            if (dRemainder == 0.5)
            {
                if (dInt % 2 != 0)      // Means the number is odd
                    dRet = (dInt + 1) * Math.Pow(10, -nDigits);
                else
                    dRet = dInt * Math.Pow(10, -nDigits);
            }
            else
                dRet = Math.Round(dNumber, nDigits, MidpointRounding.AwayFromZero);


            return dRet;
        }

 

Notice that calling Math.Round(dNumber, nDigits, MidpointRounding.AwayFromZero); will round the same way as NormalizeDouble...if you were looking to have C# code act the same way as your EA.

 

Cheers

 

a bit late :) 

but how about

   
double rounded = StringToDouble(DoubleToString(myDoubleIWishToRound, Digits));
Reason: