Android Question Float too dirty

Saverio

Member
Licensed User
Longtime User
The Code is this:
B4X:
Dim S As String
Dim F As Float = 5.55
S=F
Log(S)
Log(F)

The problem is that I will get a very long float at log, something like 5.550000190734863

But, what is more strange is that: if you pause the app and watch debug frame you will see
the "F" variable correct and the "S" variable come with wrong long number.

I've tried that either on a real phone and emulator. Got same result

The question is:
Do Someone of you know somenting about this?

img10.jpg

Thank you
Saverio
 

LucaMs

Expert
Licensed User
Longtime User
The Code is this:
B4X:
Dim S As String
Dim F As Float = 5.55
S=F
Log(S)
Log(F)

The problem is that I will get a very long float at log, something like 5.550000190734863

But, what is more strange is that: if you pause the app and watch debug frame you will see
the "F" variable correct and the "S" variable come with wrong long number.

I've tried that either on a real phone and emulator. Got same result

The question is:
Do Someone of you know somenting about this?

View attachment 24156

Thank you
Saverio


Damn, finally I understood the first post! (eureka :D)

Saverio pointed out that the "debugger" displays an incorrect value. Only this.
 
Upvote 0

Saverio

Member
Licensed User
Longtime User
@Informatix,

I agree at all with you.
But I don't care whether it's a B4A problem or not.
Anyway, for me, B4A is an awesome tool.
I can choose several workarounds to get back the right result.

I'm trying to understand which policy there is behind the Log function.

I will explain myself better.

As in the post #5 and #7, in Log(m), I'm passing the radix only.
If I understand well, Log is looking inside m for any field, and then, transform it into a string.
So if Log is searching by itself for a value inside a class, it will show the correct one.
Instead, if I pass a full name of a field (Log(m.F)) it will show what isn't correct. (5.550000190734863)
I could understand 5.56 or 5.54 as rounded values but not that "dirty" number.

Even the conversion, as you said, is not straightforward, let me say that this is a bit strange.

Regards
Saverio
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
Please,
read carefully post #5, post #7 and post #9.

Log(m.F) return 5.550000190734863 (inaccuracy)
Log(m) return F=5.55 (where is the inaccuracy?)
I think the problem here is that you think they are printing out 2 different values. They are both actually printing the same value, just presenting it in 2 different ways. 5.55 cannot be stored in memory perfectly using floats. The computer will store the closest it can. In this case, somewhere near 5.550000190734863. When you go to print it out with Log(), that value must first be converted to a string. You don't need to convert explicitly, the compiler will do it automatically for you.
More digits are being converted in the first case than in the second case. The second case finishes the conversion before reaching the end of the trailing 0s and so prints only 5.55, which resembles the original only coincidentally. Try this as an experiment. Modify your code above, replacing 5.55 with 5.550000190734863. You will see the exact same output, now the originally "accurate" output will be inaccurate with 5.55
B4X:
Sub Globals
  Type myType(F As Float)
End Sub

Sub Activity_Create(FirstTime As Boolean)

  Dim m As myType
  m.F = 5.550000190734863

  Log(m.F) ' here the result is: 5.550000190734863
  Log(m)  ' here the result is: [IsInitialized=false, F=5.55]

End Sub
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
@Informatix,
As in the post #5 and #7, in Log(m), I'm passing the radix only.
If I understand well, Log is looking inside m for any field, and then, transform it into a string.
So if Log is searching by itself for a value inside a class, it will show the correct one.
Instead, if I pass a full name of a field (Log(m.F)) it will show what isn't correct. (5.550000190734863)
I could understand 5.56 or 5.54 as rounded values but not that "dirty" number.

You posted your reply while I was still typing mine above. :)
When you type Log(m), it is not showing the correct number, but rather only a portion of the incorrect number. When you do Log(m.F) you are showing more of the incorrect number. It just happens that in the first case, the conversion stops before reaching the incorrect portion.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
If I understand well, Log is looking inside m for any field, and then, transform it into a string.
Not exactly. As you can see in the Java source generated by B4A, the parameter given to Log is converted to a string by functions like NumberToString or ObjectToString. Behind these functions, there's a call to String.valueOf. So, in most cases, there's no reason to have a difference between the value and its string representation written by Log, but in the particular case of a float value, it's Log that's responsible for the difference because the function does not call the toString function of the Float class, nor String.valueOf. It does an unneeded conversion to Double that should be avoided.
If you don't care of that, so what's your question exactly? Because between the first post and the last above, it's difficult to follow you.

I could understand 5.56 or 5.54 as rounded values but not that "dirty" number.
The Float class would be not really useful if it has a precision limited to 2 digits !
 
Last edited:
Upvote 0

Saverio

Member
Licensed User
Longtime User
If you don't care of that, so what's your question exactly? Because between the first post and the last above, it's difficult to follow you.
As I said in the post #5, It's just to know

Now I know something more! Thanks

I want leave here the following code.
Might it be useful for someone.
B4X:
sub ShowDigit
    Dim jo As JavaObject 
    Dim f As Float = 1.1111111 '7 decimals
   
    'both of following two code rows are valid
    'Initialize jo directly with the class type
    jo.InitializeStatic("java.lang.Float")
    'Let the system get the class type
    'jo=f                                   
   
    'will show 6 decimals due to float nature with the
    'integer part set to a non zero value
    Log(jo.RunMethod("toString", Array As Object(f)))

    f = 0.1111111
    'will show 7 decimals due to float nature with the
    'integer part set to zero value       
    Log(jo.RunMethod("toString", Array As Object(f)))
   
    Dim d As Double = 1.1111111111111111 '16 decimals
   
    'both of following two code rows are valid
    'Initialize jo directly with the class type
    jo.InitializeStatic("java.lang.Double")
    'Let the system get the class type
    'jo=d                                   
   
    'will show 15 decimals +1 rounded due to Double nature with the
    'integer part set to a non zero value
    Log(jo.RunMethod("toString", Array As Object(d)))

    d = 0.1111111111111111 '16 decimals
    'will show 16 decimals due to Double nature with the
    'integer part set to zero value       
    Log(jo.RunMethod("toString", Array As Object(d)))
end sub

Regards
Saverio
 
Upvote 0
Top