Other Quiz #7 - Rounding errors

thedesolatesoul

Expert
Licensed User
Longtime User
It depends on which kind of 'round' the language is implementing.
I believe for Java this will:
1. Work correctly
2. Always work correctly

Because:
The java.lang.Math.round(float a) returns the closest int to the argument. The result is rounded to an integer by adding 1/2, taking the floor of the result, and casting the result to type int.

I would like to know if I am wrong.
 
Upvote 0

cjolly

Member
Licensed User
Longtime User
1. Yes.
2. No.

Happy Christmas!

MC73, in my experience, you're right:

1. Yes
2. No

Statistically, rather than 0.5, I use a value between 0.46 and 0.49 for achieving a more accurate and automatic rounding integer.

Merry Christmas and Happy New Year to all forum members
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
If it breaks in any one case, it is not correct code.
I agree.

The two questions are a hint that you should think about it more carefully...

I actually encountered this issue today while implementing anchoring features in the designer. Took me a while to understand why the numbers are not rounded correctly in some cases.
 
Upvote 0

kmap

Member
Licensed User
Longtime User
it wont work always as
if both d and f are int the result will be int and then we dont need to round it



may be use
Dim i As Int = Round(d *1.0 / f)
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
if both d and f are int the result will be int and then we dont need to round it
The calculation was just an example. You can ignore it.

(2 notes:
- When you divide two integers the result will be a double => 2 / 3 = 0.6666...
- It is perfectly fine to round an integer. The result should still be correct.
)
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. Yes
2. Only if the result is positive
This is the correct answer.
The rounding will only be correct if the value is positive.

B4X:
Dim i As Int
i = 1.2 + 0.5
Log(i) '1
i = 1.7 + 0.5
Log(i) '2
i = -1.2 + 0.5
Log(i) '0 <--- WRONG
Log(Round(-1.2)) '-1 <-- correct result

Beware of premature optimizations...
 
Upvote 0

Pantelis

Member
Licensed User
Longtime User
I found that interesting, so I made some experimentation and found that
the results in positive numbers are same for both methods if value is smaller or equal to the maximum value for a variable of type int.
(2147483647). After this we have different value in I.

For example:

B4X:
Dim I , J As Int
Dim A As Double

A = 2147483647
I = A + 0.5       
J = Round(A)       
Log(I)        ' 2147483647
Log(J)        ' 2147483647 same results. Correct values

A = 2147483648
I = A + 0.5       
J = Round(A)       
Log(I)        ' 2147483647    minus 1
Log(J)        ' - 2147483648 negative value.

A = 2147483648000
I = A + 0.5       
J = Round(A)       
Log(I)        ' 2147483647    if the value is bigger than  2147483647, the value of I remains 2147483647
Log(J)        ' 0
 
Upvote 0

pjo12345

Active Member
Licensed User
Longtime User
Hello,

I use this code.

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.   
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim Edittext1 As EditText
    Dim Label1 As Label
    Dim Button1 As Button
    Dim EditText2 As EditText
    Dim Label2 As Label
    Dim Label3 As Label
    Dim Label4 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
Sub newRound (Value As Double, Decimal As Byte) As Double
    Dim Vorzeichen As Byte
    If Value < 0 Then
        Vorzeichen = -1
    Else If Value > 0 Then
        Vorzeichen = 1
    Else If Value = 0 Then
        Vorzeichen = 0
    End If
    Decimal = Power(10,Decimal) ' Power = 10^Decimal
    Value = (Value * Decimal) + (Vorzeichen * 0.5)
    Dim sma As String
    sma = Value
    If sma.IndexOf(".") <> -1 Then
        sma = sma.SubString2(0,sma.IndexOf(".")) 'Ganzahl bilden
    End If
    Value = sma / 100
    Return Value
End Sub

Sub Button1_Click
    Dim Z As Double
    Dim X As Int
    Z = Edittext1.Text
    X = EditText2.Text
    Z= newRound(Z,X)
    Label1.Text = Z
End Sub
 

Attachments

  • newRound.zip
    7.4 KB · Views: 297
Upvote 0
Top