none
How to only use the decimal part of one number RRS feed

  • Question

  • Hi

    I have in a variable an number, for instance 7.956 but I was wondering if there is a way to only get the number thats after it. for instance if in the variable i had the number 7.596 I would only want the 596 out of it.

    thanks in advance

    Monday, May 21, 2012 4:21 PM

Answers

  • 7.596  - Math.Floor( 7.596)
    • Proposed as answer by AshkoreDracson Monday, May 21, 2012 5:27 PM
    • Marked as answer by alex wetton Tuesday, May 22, 2012 6:10 AM
    Monday, May 21, 2012 4:26 PM
    Answerer
  • Try:

    dayssincelunar = dayssincelunar - math.floor(dayssincelunar)

    • Marked as answer by alex wetton Tuesday, May 22, 2012 4:48 PM
    Tuesday, May 22, 2012 7:57 AM
    Moderator
  • Hello Alex!

    I've made a code snippet to separate the integer & fractional parts from a number.

    Just make Number = {value to split}, call NumberSplit() subroutine, and then you get the results inside Whole & Fractional variables!

    Here's the code:

    Sub NumberSplit
      ' ---  Separates the Whole & Fractional parts of Number apart
      
      '  Makes sure Number is a valid number value:
      Number = Number * 1
      
      '  Finds where the float point is within Number:
      DotPos = Text.GetIndexOf(Number  ".")
      
      If DotPos > 0 Then  '  If a point was found, extracts what is before & what is after it!
        Whole = Text.GetSubText(Number  1  DotPos-1)
        Fractional = Text.GetSubTextToEnd(Number  DotPos+1)
      Else
        Whole = Number    '  Otherwise, the Number itself is the Whole part
        Fractional = ""   'and there's no fraction part!
      EndIf
      
      '  Makes the Whole part empty in case it is null:
      If Whole = 0 Then
        If Number >= 0 Then
          Whole = ""
        Else
          Whole = "-"
        EndIf
      EndIf
      
    EndSub

    A sample code bellow:

    Number = -00034.025
    NumberSplit()
    TextWindow.WriteLine("Whole: " + Whole)
    TextWindow.WriteLine("Fractional: " + Fractional)

    Any doubts, just ask!

    Tuesday, May 22, 2012 10:07 PM
    Answerer

All replies

  • 7.596  - Math.Floor( 7.596)
    • Proposed as answer by AshkoreDracson Monday, May 21, 2012 5:27 PM
    • Marked as answer by alex wetton Tuesday, May 22, 2012 6:10 AM
    Monday, May 21, 2012 4:26 PM
    Answerer
  • so could i put the variable name so forinstance if the variable was abc then:

    abc - math.floor(abc)

    would that be correct thanks

    Monday, May 21, 2012 7:49 PM
  • Yes, absolutely. 

    Part of the fun of programming is just trying stuff and learning by trial and error - so if you think something may work, have a go and try it; experiment and if it doesn't make sense or doesn't work as you expect, then ask.

    Please also mark gungan37's reply as the answer (so anyone else checking the question can quickly locate the answer and the question is flagged as answered so those looking for problems to help with can pass on by).

    Monday, May 21, 2012 8:01 PM
    Moderator
  • Thanks for the anwers everyone, I have tried to do it by writing the line of code:

    dayssincelunar - math.floor(dayssincelunar)

    (dayssince is the varible) but every time I try to run the program it says unrcognized statement occured at 75:16 which is where the dash(-) is. Im not sure why though. Here is the code that is above it.

    daysincelunar=daysince/29.35059
    TextWindow.WriteLine(dayssincelunar)
    dayssincelunar - math.floor(dayssincelunar)
    TextWindow.WriteLine(dayssincelunar)

    thanks in advance for any answers, as I am very new to small basic and computer programing.

    Tuesday, May 22, 2012 6:19 AM
  • Try:

    dayssincelunar = dayssincelunar - math.floor(dayssincelunar)

    • Marked as answer by alex wetton Tuesday, May 22, 2012 4:48 PM
    Tuesday, May 22, 2012 7:57 AM
    Moderator
  • Thanks that works, also is there anyway that I can get it to get rid of the (0.) so for instance turn 0.12 into 12

    thanks

    Tuesday, May 22, 2012 4:47 PM
  • One way is to multiply it by 100, but this assumes there is always exactly 2 decimal places.

    Also check your spelling, sometimes you have daysincelunar and sometimnes dayssincelunar

    Another way is to treat the number as a string and remove the first two characters (the 0.), something like:

    daysince = 15
    dayssincelunar = daysince/29.35059
    dayssincelunar = dayssincelunar - math.floor(dayssincelunar)
    TextWindow.WriteLine(dayssincelunar)
    pos = Text.GetIndexOf(dayssincelunar,".") 'Which character is the decimal point at (held in variable pos)
    fractionalPart = Text.GetSubTextToEnd(dayssincelunar,pos+1) 'Get everything after the decimal point
    TextWindow.WriteLine(fractionalPart)

    Tuesday, May 22, 2012 6:42 PM
    Moderator
  • Hello Alex!

    I've made a code snippet to separate the integer & fractional parts from a number.

    Just make Number = {value to split}, call NumberSplit() subroutine, and then you get the results inside Whole & Fractional variables!

    Here's the code:

    Sub NumberSplit
      ' ---  Separates the Whole & Fractional parts of Number apart
      
      '  Makes sure Number is a valid number value:
      Number = Number * 1
      
      '  Finds where the float point is within Number:
      DotPos = Text.GetIndexOf(Number  ".")
      
      If DotPos > 0 Then  '  If a point was found, extracts what is before & what is after it!
        Whole = Text.GetSubText(Number  1  DotPos-1)
        Fractional = Text.GetSubTextToEnd(Number  DotPos+1)
      Else
        Whole = Number    '  Otherwise, the Number itself is the Whole part
        Fractional = ""   'and there's no fraction part!
      EndIf
      
      '  Makes the Whole part empty in case it is null:
      If Whole = 0 Then
        If Number >= 0 Then
          Whole = ""
        Else
          Whole = "-"
        EndIf
      EndIf
      
    EndSub

    A sample code bellow:

    Number = -00034.025
    NumberSplit()
    TextWindow.WriteLine("Whole: " + Whole)
    TextWindow.WriteLine("Fractional: " + Fractional)

    Any doubts, just ask!

    Tuesday, May 22, 2012 10:07 PM
    Answerer
  • Thanls for writing the code and explaining it to me it was very useful and it has now worked.
    Wednesday, May 23, 2012 5:07 PM
  • I've added into NumberSplit() a code to trim any possible leftover zeros at the end of the Fractional part.

    And created NumberMerge() subroutine to glue Whole & Fractional into Number together again.

    Sub NumberSplit
      ' ---  Separates the Whole & Fractional parts of Number apart
      
      '  Makes sure Number is a valid number value:
      Number = Number * 1
      
      '  Finds where the float point is within Number:
      DotPos = Text.GetIndexOf(Number  ".")
      
      If DotPos > 0 Then '  If a point was found, extracts what comes before & what goes after it!
        Whole = Text.GetSubText(Number  1, DotPos-1)
        Fractional = Text.GetSubTextToEnd(Number  DotPos+1)
      Else
        Whole = Number   '  Otherwise, the Number itself is the Whole part
        Fractional = ""  'and there's no fraction part!
      EndIf
      
      '  Makes the Whole part empty in case it is null:
      If Whole = 0 Then
        If Number >= 0 Then
          Whole = ""
        Else
          Whole = "-"
        EndIf
      EndIf
      
      '  Trims any leftover zeros at the end of Fractional:
      While Text.EndsWith(Fractional  0)
        Fractional = Text.GetSubText(Fractional  1, Text.GetLength(Fractional)-1)
      EndWhile
      
    EndSub
    
    Sub NumberMerge
      ' ---  Glues Whole & Fractional parts into Number together again
      
      If Fractional <> "" Then
        Number = Text.Append(Whole + "."  Fractional)
      Else
        Number = Whole
      EndIf
     
      If Number = "" Then
        Number = 0
      EndIf EndSub

    And an example code on how to use both:

    Number = "-00034.025000"
    TextWindow.WriteLine("Original: " + Number)
    
    NumberSplit()
    TextWindow.WriteLine("Whole: " + Whole)
    TextWindow.WriteLine("Fractional: " + Fractional)
    
    NumberMerge()
    TextWindow.WriteLine("Reassembled: " + Number)

    That's all folks!

    Wednesday, May 23, 2012 11:23 PM
    Answerer
  • Hi Alex,

    I'm only new to SmallBasic and am having great fun teaching it to my 11year-old.

    All the suggestions so far look great but I though both the Math.Floor and text approaches could be combined to reduce the amount of code:

    frac = num - Math.Floor(num)
    If frac <> 0 Then
      frac = Text.GetSubTextToEnd(frac,3)
    EndIf
    
    

    Since the fractional part will always start with "0." (unless it is 0) just treat it like a string and skip to taking from the third character to the end!

    As I say, I'm only starting with SmallBasic so if this is the wrong way to approach the solution then at least I'll have found out something new :-)

    Cheers,

    Conor.

    Thursday, May 31, 2012 1:58 PM
  • Hello ConorM0! Welcome aboard!

    Your hybrid approach is very short and elegant but... once a number is negative, it fails miserably due to the way how Math.Floor() works!

    The premise is that Math.Floor() has to return the 1st integer <= than the passed argument. Some examples:

    Math.Floor(5.5)    = 5
    Math.Floor(0.0001) = 0
    Because 5 < 5.5   &   0 < 0.0001

    But what happens when the passed argument is a negative value?

    Math.Floor(-5.5)    = -6 and NOT -5
    Math.Floor(-0.0001) = -1 and NOT  0
    Why? Because -6 < -5.5   &   -1 < -0.0001

    To remove the fractional part of a negative value the same way as Math.Floor() does for positive values, Math.Ceiling() has to be used in its place!

    Math.Ceiling() does the opposite of Math.Floor(). It returns the 1st integer >= than the passed argument. Now it works:

    Math.Ceiling(-5.5)    = -5
    Math.Ceiling(-0.0001) =  0
    -5 > -5.5   &   0 > -0.0001

    But wait! There's another problem: your code assumes that the decimal point is always placed at 2nd position after a -> fract = num - Math.Floor(num)
    But with an extra minus sign, the decimal point is now at 3rd position!

    Here's your hybrid solution fixed to work on negative values as well:

    num = "-001350.7099000"
    
    If num < 0 Then
      fract = num - Math.Ceiling(num)
      pos   = 4
    Else
      fract = num - Math.Floor(num)
      pos   = 3
    EndIf
    
    If fract <> 0 Then
      fract = Text.GetSubTextToEnd(fract  pos)
    EndIf

    TextWindow.WriteLine("Fraction -> " + fract)

    It sure got a lil' fatter now!  :-D

    But do not fret, there's another solution!
    Since we're only interested at extracting the fractional part, we can ignore its sign!
    We can simply use Math.Abs() to always obtain a positive value from num. Here's how:

    num = "-001350.7099000"
    FractionExtract()
    TextWindow.WriteLine("Fraction -> " + fract)
    
    Sub FractionExtract
    
      tmp = Math.Abs(num)
      fract = tmp - Math.Floor(tmp)
    
      If fract <> 0 Then
        fract = Text.GetSubTextToEnd(fract  3)
      EndIf
    
    EndSub

    And with the extra benefit that only now I've found out -> Math.Abs() removes the extra meaningless floating point zeros!!!
    For num = "-001350.7099000", the Math.Ceiling() version returns fract = 7099000
    But the Math.Abs() one returns the cleanly scrubbed fract = 7099!!!
    So, no need for a separate fractional zero trim process like the one below:  (^_^)

    While Text.EndsWith(Fract  0)
      Fract = Text.GetSubText(Fract  1, Text.GetLength(Fract)-1)
    EndWhile

    I know that is a collateral aesthetic bug due to the fact SB only having the string value type!

    And although Math.Abs() fix that problem, it creates another one by removing the sign of the value!

    So after looking all the Math object's operators, I've found out another one which does the same as Math.Abs(), but w/o changing its value at all: Math.Power(num, 1)!
    It's logical, any value raised by exponent 1 is the value itself; but now all tidied up and shiny after the process!  ;-P

    Whew! This was a long discourse. See you later!


    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    Saturday, June 2, 2012 3:07 AM
    Answerer