Android Question Floating point error

carlos7000

Active Member
Licensed User
I am writing a simple program that must add the number 0.000000000000001 a given number of times.

something like that

B4X:
Do While Cycles > 0
    Cycles = Cycles - 1
    Total = Total + 0.000000000000001
Loop
Strangely, the answer does not match what was expected. I was reducing the requirement of the operation by testing with different values such as:

0.000000000000001
0.00000000000001
0.0000000000001
0.000000000001
0.00000000001
0.0000000001
0.000000001
0.00000001
0.0000001
0.000001
0.00001
0.0001
0.001
0.01
0.1

For example something as simple as when the program is instructed to add 0.1, 50000 times, the result should give 5000, really gives 5002.529296875

B4X:
Do While Cycles > 0
    Cycles = Cycles - 1
    Total = Total + 0.1
Loop
The complete code of the program is:

B4X:
#Region  Project Attributes 
    #ApplicationLabel: Test Float
    #VersionCode: 2
    #VersionName: 
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes 
    #FullScreen: False
    #IncludeTitle: True
#End Region

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.

    Private ButtonRun As Button
    Private LabelCalculos As Label
    Private EditText1 As EditText
    Private LabelTiempo As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub ButtonRun_Click
    Test   
End Sub

Sub Test
    Try
        ButtonRun.Enabled = False
        Dim Time1 As Long
        Dim time2 As Long
        Dim Cicles As Int
       
        Cicles = EditText1.Text
   
        Dim Total As Float
        Total = 0
   
        Time1 = DateTime.Now
        Do While Cicles > 0
            Cicles = Cicles - 1
            'Total = Total + 0.000000000000001 -> Error
            'Total = Total + 0.00000000000001 -> Error
            'Total = Total + 0.0000000000001 -> Error
            'Total = Total + 0.000000000001 -> Error
            'Total = Total + 0.00000000001 -> Error
            'Total = Total + 0.0000000001 -> Error
            'Total = Total + 0.000000001 -> Error
            'Total = Total + 0.00000001 -> Error
            'Total = Total + 0.0000001 -> Error
            Total = Total + 0.1 
        Loop       
        time2 = DateTime.Now
   
        LabelCalculos.Text = NumberFormat2(Total, 1, 14, 14, False)       
        LabelTiempo.Text = time2 - Time1
       
        ButtonRun.Enabled = True
    Catch
        Log(LastException)
    End Try
End Sub
I made a similar program in B4J and the result was the same.

I attach the project for which you want to prove it.
 

Attachments

Erel

Administrator
Staff member
Licensed User
1. 0.1 can't be stored 100% accurately in a floating point number.
2. You should never convert a number to a string without using NumberFormat. In most cases this will be enough to discard the rounding errors. However if it is not enough for your requirements then you should use BigDecimal from BigNumbers library: https://www.b4x.com/android/forum/threads/bignumbers-library.9540/#content
 
Top