Android Question “Solved” How to get the decimal part of a number?

Sergey_New

Well-Known Member
Licensed User
Longtime User
B4X:
Dim latitude As Double=43.123456
Dim m As Long
'...
' need to get the value m=123456
How to do it?
 

TILogistic

Expert
Licensed User
Longtime User
?
B4X:
    Dim latitude As Double= 43.123456
    Dim latitude As Double= 43
    Dim latitude As Double= .123456
    Dim m() As String = Regex.Split("\.", latitude)
    Log(IIf(m.Length = 1, 0, m(1)))
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
if you deal with numbers i think it is better to not convert it to string.
@Jeffrey Cameron gave you the correct answer in my opinion


it is better to stay with numbers when you deal with numbers.
 
Upvote 0

cklester

Well-Known Member
Licensed User
Would this not work?
B4X:
    Dim pVal As Double = 43.123456
    Dim pDec As Double = pVal - Floor(pVal)
    Log(pDec)

One of the problems with this approach is the rounding errors that can occur.

e.g.,

Example of Rounding Errors:
Sub AppStart (Args() As String)
    Log("Hello world!!!")
    Private num As Double = 31.987654321
    
    'inting
    Log(num.As(Int))
    Log(num-num.As(Int))

    'flooring
    Log(Floor(num))
    Log(num-Floor(num))

End Sub

resulting in

Hello world!!!
31
0.9876543210000008
31
0.9876543210000008

The best approach has to be converting it to a string first. That way, you avoid these slight rounding errors.
 
Upvote 0

ilan

Expert
Licensed User
Longtime User

sorry but i dont understand.
you are dealing with doubles so why do you convert it to a int?

the best way to do it is just taking the double.
using floor to get the whole number before the decimal point and then substract the origin number with the whole number only.

as @Jeffrey Cameron did.
if you conert to string and start spliting the string you may get errors like

if there is no point in the number or if the phone instead of dot use comma "," you may get a crash.
 
Upvote 0

cklester

Well-Known Member
Licensed User
sorry but i dont understand.
you are dealing with doubles so why do you convert it to a int?

It's the same effect as flooring. Look closely at the results again...

31
0.9876543210000008
31
0.9876543210000008

The original number is 31.987654321. Both int() and floor() achieve the same result... and both are wrong.


the best way to do it is just taking the double.
using floor to get the whole number before the decimal point and then substract the origin number with the whole number only.

That's exactly what I showed in my example. And the result is wrong.
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
To be honest, I didn't actually test this, that is why I phrased my reply as a question.

After running it in B4J it does appear that there is some conversion happening internally that is producing rounding errors. Honestly, 99% of my work is in VB.NET and I stopped using Double in favor of the Decimal datatype years ago and it does not suffer from this problem. When I ran this in B4J it came up with "0.12345599999999735" as the log result.

When I run this in VB.NET with the Decimal datatype, it produces the expected result:
B4X:
        'VB.NET code
        Dim pVal As Decimal = 43.123456
        Dim pDec As Decimal = pVal - Math.Floor(pVal)
        Debug.Print("Value is " & pDec)

        'output shows "Value is 0.123456"

So, given the inherent inaccuracies of the Double datatype, perhaps a string solution (albeit less efficient) is the best answer. I would probably format the value to ensure the value is the expected type:
B4X:
    Dim pVal As Double = 43.123456789
    Dim psVal As String = $"$0.9{pVal}"$
    Log(psVal.SubString(psVal.IndexOf(".")+1))
This shows the expected "123456789"
 
Last edited:
Upvote 0

ilan

Expert
Licensed User
Longtime User
It's the same effect as flooring. Look closely at the results again...
The original number is 31.987654321. Both int() and floor() achieve the same result... and both are wrong.




That's exactly what I showed in my example. And the result is wrong.
you are right i see it now, it is really weird
 
Upvote 0

epiCode

Active Member
Licensed User
B4X:
Sub DecimalPart ( dblstr As Double ) As String
    If dblstr-Floor(dblstr) = 0 Then Return "0" Else  Return Regex.Replace("^[\d].\.*",dblstr.As(String),"")
End Sub

- Returns full String
- no rounding issues
- returns "0" when there is no decimal part
- returns leading zeroes for example 21.0023 will return 0023 as string and not 23.
 
Upvote 0

Cosmo

Member
For positive values:
Convert the decimal value 'a' to an integer 'b'
Convert b to a decimal value
subtract a-b, the result is the decimal part of your number.

HTH, regards
 
Upvote 0

Raart

Member
Here the decimal part of a negative number results to be positive. This is incorrect.
-2 + 0.36 is not -2.36 but -1.64.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…