# Android QuestionRound2 limits/errors

#### Roger Daley

##### Well-Known Member
Longtime User
Hi all,

A question on the limits of Round2(Number, Decimalplaces). I have found that Round2 returns incorrect results if the combination of Number and Decimalplaces becomes large.
For example:
1. Round2(1.23456789, 18) produces the expected result but Round2(1.23456789, 20) gives 0.09223372
2. Round2(123456.123456, 14) produces 92.23372037E3
The bigger the "Number" the smaller the possible "Decimalplaces"
Obviously the internal process of Round2 is producing "out of range numbers" without a trap/limit/flag.

My question is, does anyone know how to determine the limits the Round2 arguments to an acceptable combination range?

Any help much appreciated

Regards Roger

#### Roger Daley

##### Well-Known Member
Longtime User
Hi all,

Solution has come to mind, I will post here for others.

Sub MaxRound(Numb)
'Sub to determine the maximum number of decimal places to which "Numb" can be rounded using
'Round2 (Number As Double, DecimalPlaces As Int) As Double

Dim temp1 As Double
Dim MaxRounding As Int
temp1 = Logarithm(Numb,10) 'Take logarithm of number to be rounded
temp1 = Round2(temp1,0) 'Resulting Logarithm rounded to an interger
MaxRounding = 18 - temp1 'Calculate maximum rounding digit as interger
Msgbox(MaxRounding, "Maximum number of digits to which the number can be rounded")
End Sub

Regards Roger

#### Erel

##### B4X founder
Staff member
Longtime User
It is better to use NumberFormat or NumberFormat2 instead of Round or Round2. It was a mistake to add Round2.

#### Alberto Michelis

##### Well-Known Member
Longtime User
Im working with graphs and need to roun the max value for the Y axis.
If I have for example max=280, which function to use to obtain 300?
thanks

#### Roger Daley

##### Well-Known Member
Longtime User
Alberto,

I don't quite understand the question or see how rounding is involved.
Can you give a more detailed example. If you need to round a number use Numberformat, otherwise use the Max/Min functions.

Regards Roger

#### Erel

##### B4X founder
Staff member
Longtime User
I think that you are looking for:
B4X:
``Dim roundedValue As Int = 100 * Round(value / 100)``

#### Roger Daley

##### Well-Known Member
Longtime User
Alberto,

Seeing Erels reply I think I now understand what you are trying to do.

B4X:
``````Dim roundedValue As Int = 100 * Round(value / 100)
Value=Max=280
roundedValue=300    'Y Axis  fits Max
or
Value=Max=240
roundedValue=200    'Y Axis  does not fit Max``````

I suggest you try the Ceil function instead of the Round function. If your max=240 using the Round function would give a Y axis of 200.

Below "N" is determined by the size of Max. IE Max >=10 and Max< 100 "N"=10 Etc.

B4X:
``````Dim YAxisValue As Int = N * Ceil(value / N)
N=100
Value=Max=280
YAxisValue=300    'Y Axis  fits Max
or
Value=Max=240
YAxisValue=300    'Y Axis  fits Max``````

Regards Roger

#### Mahares

##### Expert
Longtime User
B4X:
``````Log("MyRound:" & RoundValue(161.93)) 'displays 200
Log("MyRound:" & RoundValue(906.8)) 'displays 1000
Log("MyRound:" & RoundValue(-70)) 'displays -100
Log("MyRound:" & RoundValue(280)) 'displays 300
Log("MyRound:" & RoundValue(-280)) 'displays -300``````
B4X:
``````Sub RoundValue(x As Double) As Int
If x > 0 Then
Return 100 * Ceil(x / 100)
Else
Return 100 * Floor(x / 100)
End If
End Sub``````

#### Roycefer

##### Well-Known Member
Longtime User
And for those who like shoving as much execution as possible into one line at the expense of readability:
B4X:
``````Sub RoundedValue(x As Double) As Int
Return (x/Abs(x)) * 100 * Ceil(Abs(x)/100)
End Sub``````

If your y-axis could be any value within the Int range, you probably don't want to be rounding up to the next hundred. If value=1,854,025, you probably don't want your y-axis to go up to 1,854,100, you probably want it to go up to 2,000,000.
B4X:
``````Sub RoundedValueGeneral(x As Double) As Int
Return (x/Abs(x)) * Power(10,Floor(Logarithm(Abs(x),10))) * Ceil(Abs(x)/Power(10,Floor(Logarithm(Abs(x),10))))
End Sub``````

#### Roger Daley

##### Well-Known Member
Longtime User
And for those who like shoving as much execution as possible into one line at the expense of readability:
B4X:
``````Sub RoundedValue(x As Double) As Int
Return (x/Abs(x)) * 100 * Ceil(Abs(x)/100)
End Sub``````

If your y-axis could be any value within the Int range, you probably don't want to be rounding up to the next hundred. If value=1,854,025, you probably don't want your y-axis to go up to 1,854,100, you probably want it to go up to 2,000,000.
B4X:
``````Sub RoundedValueGeneral(x As Double) As Int
Return (x/Abs(x)) * Power(10,Floor(Logarithm(Abs(x),10))) * Ceil(Abs(x)/Power(10,Floor(Logarithm(Abs(x),10))))
End Sub``````

Roycefer,

Re-looked at this again and I have say I am impressed, especially if you wrote that line in one breath. ... and you have simplified a different problem for me. Thanks.

Roger

#### Roycefer

##### Well-Known Member
Longtime User

The RoundedValueGeneral() sub is an interesting case study in code style choices. While it is certainly the tersest implementation of that logic (it all executes in one line, after all), it is probably not the most efficient implementation. We are forcing the processor to calculate Power(10,Floor(Logarithm(Abs(x),10))) twice, whereas if we did this:
B4X:
``````Sub RoundedValueGeneral(x As Double) As Int
Dim powfllog as Double = Power(10,Floor(Logarithm(Abs(x),10)))
Return (x/Abs(x)) * powfllog * Ceil(Abs(x)/powfllog)
End Sub``````
the processor only has to calculate it once and retrieve it from L1 cache twice, possibly making it a bit faster. Terse isn't always most efficient. You should add that to your B4Zen wisdom.

Replies
2
Views
427
Replies
3
Views
572
Replies
5
Views
3K
Android Question Round2 not working fine.
Replies
1
Views
762
Replies
5
Views
6K