Android Question Rounding Numbers: Round2 or Numberformat2

Roger Daley

Well-Known Member
Licensed User
Longtime User
This is an answer to a question raised in my mind by a comment from Erel, that I should not use Round2 but use Numberformat2 for rounding numbers.

Most of us are taught that for digits below 5, round down, for 5 and greater round up.
IE 4.725 to 2 decimal places gives 4.73. This is the result given by Round2.
Numberformat2 gives the result 4.72 after a bit of research I found that this is correct. Always rounding up 5 is simplistic and produces errors.

The more accurate method [simplistically put] is if the digit preceding the 5 is even, round down, if it is odd, round up.
IE 4.725 to 2 decimal places is 4.72. 4.735 to 2 decimal places is 4.74.
Numberformat2 gives these results.

This link gives a much better/precise explanation:
http://www.chemteam.info/SigFigs/Rounding.html

Thanks to Erel for helping correct a misconception I have carried for most of my life.


Regards Roger
 

derez

Expert
Licensed User
Longtime User
I must disagree because there are 5 cases to round down ( 0,1,2,3,4) and 5 for up (5,6,7,8,9)
If you take the suggested method, at least correct it to this (taken from here http://math.about.com/od/arithmetic/a/Rounding.htm) :
This rule provides more accuracy and is sometimes referred to as the 'Banker's Rule'. When the first digit dropped is 5 and there are no digits following or the digits following are zeros, make the preceding digit even (i.e. round off to the nearest even digit). E.g., 2.315 and 2.325 are both 2.32 when rounded off to the nearest hundredth. Note: The rationale for the third rule is that approximately half of the time the number will be rounded up and the other half of the time it will be rounded down.
Example - you don't want to round 3.254 to 3.2 but to 3.3
 
Upvote 0

derez

Expert
Licensed User
Longtime User
Further explanation:
1. When we take numbers which have more than one digit that need to be rounded (like 3.254 which needs to be rounded to tenth) - we look at the continuous range of numbers between 0-5 and between 5-10, and they are with the same length, so rounding by the "round(x)" method is correct.
2. When rounding just one digit, we look at a digital range of 5 cases each - 0,1,2,3,4 and 5,6,7,8,9
so the same rule can apply - round the first group down and the second - up.
The fact that with 0 we actually do not change the number does not effect the logic because when trying to balance the mean of many rounded numbers, some of them are with that digit and count in the total.
 
Upvote 0

Roger Daley

Well-Known Member
Licensed User
Longtime User
Hi Derez,

You may be correct. Numberformat agrees with you in part, when I fed in your 3.254 example the result was 3.3.
However for 3.25 NF returns 3.2. For 3.35 NF returns 3.4.
As a humble retired technician I'll concede the maths intricacies, I'm out of my depth. For me the issue is, the choice between using Round2 and Numberformat2 for rounding. NF rounds nn.n5 up approximately half the time and down the other half. Round2 always rounds up. Numberformat2 wins.

Thanks for the input and by the way I'm still using your Scalculator code as my training exercise. Very useful and instructive.

Regards Roger
 
Upvote 0

derez

Expert
Licensed User
Longtime User
I surrender. I decided to check it in a program with the following code:
B4X:
Sub Globals
   
Dim m1,m2 ,m3 As Double
Dim n As Int = 100000
End Sub

Sub Activity_Create(FirstTime As Boolean)
Dim x, y, z As Double
For i = 1 To n
    x = Rnd(0,1000) /1000
    y = Round2(x,2)
    z = NumberFormat(x,1,2)
'    Log(x & " " & y & " " & z)
    m1 = m1 + x
    m2 = m2 + y
    m3 = m3 + z
Next
Log("n = " & n)
m1 = m1/n
m2 = m2/n
m3 = m3/n
Log("true =  " & m1 )
Log("round=  " & m2)
Log("format= " &  m3)
Log("round_dif  = " & NumberFormat((m2-m1),1,5))
Log("format_dif = " & NumberFormat((m3-m1),1,5))
End Sub

I got these results and they prove that NF is better !:
** Activity (main) Resume **
** Activity (main) Create, isFirst = true **
n = 10000
true = 0.5028684000000027
round= 0.503301000000001
format= 0.5028590000000008
round_dif = 0.00043
format_dif = -0.00001
** Activity (main) Resume **
** Activity (main) Create, isFirst = true **
n = 100000
true = 0.4999440600000005
round= 0.5004085999999968
format= 0.49993360000000014
round_dif = 0.00046
format_dif = -0.00001
 
Upvote 0
Top