Round Number

 

Hi everyone,

I write a little code for getting round number of 4 digits.

Example : 1.23455 -- > 1.2345

1.23456 --> 1.2346

my code is below. Please help me to check this code and tell me if i wrong. And, anyone have a better ideas? Please share it . Thanks

double RoundNo(double price){

   double roundprice; 
   string strprice=StringSubstr(DoubleToStr(price,5),6,1);
   if (RoundNumber)
   {
      if (StrToDouble(strprice)==5)roundprice=StrToDouble(StringSubstr(DoubleToStr(price,5),0,6));       
      else roundprice=MathRound(price*10000)/10000;
   }   
   else roundprice = price;
    
   return (roundprice);
}
 
 
bizu:

Hi everyone,

I write a little code for getting round number of 4 digits.

Example : 1.23455 -- > 1.2345

1.23456 --> 1.2346

my code is below. Please help me to check this code and tell me if i wrong. And, anyone have a better ideas? Please share it . Thanks

First, what is the variable RoundNumber and what are trying to do with the following IF statement?

if (RoundNumber)
{
   ...
}

Second, why do you need to use a string representation of the number? See the following code as an example:

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

The above code can round a number to the number of decimal digits provided.

 

Might be opening a can of worms here but why not NormalizeDouble ?


Also isnt convention to round '5' up? OP seems to want '5' rounded down which is not common as far as I know, and all posts so far might not be what OP wants (if they really do want 5 rounded down and 6 up ) ?

 
ydrol:

Might be opening a can of worms here but why not NormalizeDouble ?


Also isnt convention to round '5' up? OP seems to want '5' rounded down which is not common as far as I know, and all posts so far might not be what OP wants (if they really do want 5 rounded down and 6 up ) ?

Of course it's the simplest solution. It's not because WHRoeder don't use NormalizeDouble that you can't use it.
 
double BankersRound(double value, int precision)
{
        return(MathCeil(value*MathPow(10, precision) - 0.5) / MathPow(10, precision));
}
 
ydrol:

Might be opening a can of worms here but why not NormalizeDouble ?

Also isnt convention to round '5' up? OP seems to want '5' rounded down which is not common as far as I know, and all posts so far might not be what OP wants (if they really do want 5 rounded down and 6 up ) ?

I don't know what NormalizeDouble() does internally, but it might be useful in this situation if the only thing it does is round double to a specified precision. However, if the OP wants to round down on less than 6 (rather than on less than 5), NormalizeDouble() may not be what the OP wants.

Regarding the rounding, good catch. I admit I didn't see the special rounding condition inferred by the OP. The following code rounds down on less than 6:

double RoundNumber(double number, int digits) {
   number = MathFloor((number * MathPow(10, digits)) + 0.4);
   return (number * MathPow(10, -digits));
}
angevoyageur:
. . . It's not because WHRoeder don't use NormalizeDouble that you can't use it.
True (I think). LOL!!
 
sangmane:
double BankersRound(double value, int precision)
{
        return(MathCeil(value*MathPow(10, precision) - 0.5) / MathPow(10, precision));
}

What about the number 1.234556 with a rounding precision of 4? Shouldn't that number be rounded down to 1.2345, rather than up to 1.2346?
 
Thirteen:
What about the number 1.234556 with a rounding precision of 4? Shouldn't that number be rounded down to 1.2345, rather than up to 1.2346?

My understanding is that OP wants banker's rounding.

The interesting thing about rounding (to the nearest) is that how you should round 1.5, which is halfway between 1.0 and 2.0. In term of error, 1.0 and 2.0 produce the sane rounding error. Some people prefer to round it down, and another prefer to round it up.

 
sangmane:

My understanding is that OP wants banker's rounding.

Until you mentioned it, I hadn't considered that possibility. You have a good point. However, one of the OP's examples is: 1.23455 rounds down to 1.2345. My understanding of Banker's rounding (which is also known as "round half to even") is when a number is equidistant between two integers (i.e., a distance of 0.5 from each integer), it is rounded to the nearest even integer. Otherwise, it is rounded to the nearest integer. Using banker's rounding on the OP's example would mean that 1.23455 rounds up to 1.2346, which is the opposite of what the OP has suggested.

Also, I noticed that your code doesn't seem round to the nearest even integer. (Please correct me I'm wrong.) I think the following code gives bias to the nearest even integer when the number to be rounded is equidistant between two integers.

double BankersRound(double value, int precision) {
   value = value * MathPow(10, precision);
   if (MathCeil(value) - value == 0.5 && value - MathFloor(value) == 0.5) {   // also could use: MathCeil(value) - value == value - MathFloor(value)
      if (MathMod(MathCeil(value), 2) == 0)
         return (MathCeil(value) / MathPow(10, precision));
      else  
         return (MathFloor(value) / MathPow(10, precision));
   }
   return (MathRound(value) / MathPow(10, precision));
}
 
Interestingly . . . nothing from the OP
Reason: