decimal to fraction

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ordz

    decimal to fraction

    I want to write a program that will take a decimal with up to 4 places
    and convert it to 1/16 ths. I can sort of do that with:

    n = 375 * 16 / 1000
    Print n; "/16"

    I am planning to use an input box to enter the number with no decimal
    point.
    But I don't know how to get a count of the digits in the denominator.
    I will also round off any results that have a decimal place. I need
    to know how I can identify the number after the decimal so I can round
    it up or down. Thanks
  • Rick Rothstein

    #2
    Re: decimal to fraction

    > I want to write a program that will take a decimal with up to 4 places[color=blue]
    > and convert it to 1/16 ths. I can sort of do that with:
    >
    > n = 375 * 16 / 1000
    > Print n; "/16"
    >
    > I am planning to use an input box to enter the number with no decimal
    > point.
    > But I don't know how to get a count of the digits in the denominator.
    > I will also round off any results that have a decimal place. I need
    > to know how I can identify the number after the decimal so I can round
    > it up or down. Thanks[/color]

    I'm not so sure I understand the input mechanism you want to use; but,
    before you get started coding, you might want to take a look at the
    function at this link...

    VBnet provides Intermediate and Advanced Win32 API code for VB developers. Comprehensive Code, FAQ, Developers Resources & News, alphabetical API/Type/Constant/Method Index, along with the largest Visual Basic-related links list on the net.


    Rick - MVP

    Comment

    • Steve Gerrard

      #3
      Re: decimal to fraction


      "Rick Rothstein" <rickNOSPAMnews @NOSPAMcomcast. net> wrote in message
      news:24ednVGyl6 _dA2Td4p2dnA@co mcast.com...[color=blue]
      > I'm not so sure I understand the input mechanism you want to use; but,
      > before you get started coding, you might want to take a look at the
      > function at this link...
      >
      > http://vbnet.mvps.org/code/helpers/numbertofraction.htm
      >
      > Rick - MVP
      >[/color]

      I don't know if you were aware of this or not. If you try
      MakeFraction(1. 99, 32), you will get 1 1/1. I would suggest adding these
      lines after the do loop:
      If Denominator = 1 Then
      WholeNumber = WholeNumber + 1
      MakeFraction = CStr(WholeNumbe r)
      Else...

      Otherwise, this is a nice function to have. If you ever have to convert
      decimal feet to feet, inches, and fractional inches, you will know what
      I mean.



      Comment

      • Rick Rothstein

        #4
        Re: decimal to fraction


        "Steve Gerrard" <notstevegerrar d@comcast.net> wrote in message
        news:X_6dnSoVFJ KIWGfd4p2dnA@co mcast.com...[color=blue]
        >
        > "Rick Rothstein" <rickNOSPAMnews @NOSPAMcomcast. net> wrote in message
        > news:24ednVGyl6 _dA2Td4p2dnA@co mcast.com...[color=green]
        > > I'm not so sure I understand the input mechanism you want to use;[/color][/color]
        but,[color=blue][color=green]
        > > before you get started coding, you might want to take a look at the
        > > function at this link...
        > >
        > > http://vbnet.mvps.org/code/helpers/numbertofraction.htm[/color]
        >
        > I don't know if you were aware of this or not. If you try
        > MakeFraction(1. 99, 32), you will get 1 1/1. I would suggest adding[/color]
        these[color=blue]
        > lines after the do loop:
        > If Denominator = 1 Then
        > WholeNumber = WholeNumber + 1
        > MakeFraction = CStr(WholeNumbe r)
        > Else...[/color]

        Nope, I wasn't aware of that flaw; thanks for pointing it out. Although
        I'd note that 1 1/1 is technically correct (1+1/1=2); but, of course,
        nobody wants to see it written that way. By the way, there are lots of
        input that will degenerate to this odd format... the argument pairs
        (3.97,16), (3.98,16), (3.99,16) for example. While your change would
        work, I'm inclined to try and catch the problem earlier on. I'm thinking
        adding this

        If Numerator = Denominator Then
        Numerator = 0
        WholeNumber = WholeNumber + 1
        End If

        immediately after this line

        Numerator = Format(Denomina tor * _
        Abs(DecimalNumb er - WholeNumber), "0")

        would also work and it would avoid the Do-Loop too. I haven't looked at
        that code in some time and I obviously developed it before I was aware
        of the problems with IsNumeric. So, I'd also propose changing that test
        line too (I've added my standard IsNumber function so that it can be
        called instead of VB's IsNumeric function). Here is the final
        "corrected" code I'm thinking of sending on to Randy; do you (or anyone
        else following this thread) see any problem with it?

        Rick - MVP

        Function MakeFraction(By Val DecimalNumber As Variant, _
        Optional ByVal LargestDenomina tor As Long = 64, _
        Optional bShowDash As Boolean = False) As String

        Dim GCD As Long
        Dim TopNumber As Long
        Dim Remainder As Long
        Dim WholeNumber As Long
        Dim Numerator As Long
        Dim Denominator As Long

        If IsNumber(Decima lNumber) Then

        DecimalNumber = CDbl(DecimalNum ber)
        WholeNumber = Fix(DecimalNumb er)
        Denominator = LargestDenomina tor
        Numerator = Format(Denomina tor * _
        Abs(DecimalNumb er - WholeNumber), "0")

        If Numerator = Denominator Then
        Numerator = 0
        WholeNumber = WholeNumber + 1
        End If

        If Numerator Then
        GCD = LargestDenomina tor
        TopNumber = Numerator

        Do

        Remainder = (GCD Mod TopNumber)
        GCD = TopNumber
        TopNumber = Remainder

        Loop Until Remainder = 0

        Numerator = Numerator \ GCD
        Denominator = Denominator \ GCD

        MakeFraction = CStr(WholeNumbe r) & _
        IIf(bShowDash, "-", " ") & _
        CStr(Numerator) & "/" & _
        CStr(Denominato r)
        Else

        MakeFraction = CStr(WholeNumbe r)

        End If

        Else

        'Input wasn't a number, handle error here

        End If

        End Function


        Function IsNumber(ByVal Value As String) As Boolean

        ' Leave the next statement out if you don't
        ' want to provide for plus/minus signs
        If Value Like "[+-]*" Then Value = Mid$(Value, 2)
        IsNumber = Not Value Like "*[!0-9.]*" And _
        Not Value Like "*.*.*" And _
        Len(Value) > 0 And Value <> "." And _
        Value <> vbNullString

        End Function

        Comment

        • Steve Gerrard

          #5
          Re: decimal to fraction


          "Rick Rothstein" <rickNOSPAMnews @NOSPAMcomcast. net> wrote in message
          news:PNKdnSSkk9 Z4TWfdRVn-sQ@comcast.com. ..[color=blue]
          >[color=green][color=darkred]
          > > >
          > > > http://vbnet.mvps.org/code/helpers/numbertofraction.htm[/color]
          > >[/color]
          >. Here is the final
          > "corrected" code I'm thinking of sending on to Randy; do you (or[/color]
          anyone[color=blue]
          > else following this thread) see any problem with it?
          >[/color]

          Looks good. Testing for Numerator = Denominator before the loop is a
          smarter way to fix it.

          I would rather see
          If Numerator <> 0 Then
          in place of
          If Numerator Then
          just because I dislike seeing numbers treated as booleans, but that is
          purely a style comment.

          My one more serious wish is to have a version of IsNumber that would
          accept valid commas and currency symbols, i.e. return true for
          $7,241.25. This allows copy and paste of formatted values, for instance.
          These two lines would strip all commas and a leading currency symbol.
          It's not perfect, since $72,41.25 returns True, but it comes close.
          Value = Replace(Value, ",", "")
          If Value Like "[$]*" Then Value = Mid$(Value, 2)

          Can you make a locale independent version of IsNumber? I don't need it,
          but some users might.


          Comment

          • Rick Rothstein

            #6
            Re: decimal to fraction

            > My one more serious wish is to have a version of IsNumber that would[color=blue]
            > accept valid commas and currency symbols, i.e. return true for
            > $7,241.25. This allows copy and paste of formatted values, for[/color]
            instance.[color=blue]
            > These two lines would strip all commas and a leading currency symbol.
            > It's not perfect, since $72,41.25 returns True, but it comes close.
            > Value = Replace(Value, ",", "")[/color]

            That is how I have implemented this for past questions regarding the
            "thousands separator". Personally, I don't see any reason to *punish* a
            user for misplacing the commas as they have no bearing on the value of
            the number.

            [color=blue]
            > If Value Like "[$]*" Then Value = Mid$(Value, 2)[/color]

            That is also how I would handle it. I'm going to address your "locale
            independent version of IsNumber" question below; but since it doesn't
            involve the currency symbol, I thought I'd point out how to get it in
            case a reader wants to use the above change, but for a non-US currency
            symbol. The locale currency symbol (CS) can be obtained this way.

            CS = Left$(Format$(1 , "Currency") , 1)

            [color=blue]
            > Can you make a locale independent version of IsNumber?
            > I don't need it, but some users might.[/color]

            Your wish is my command.<g> Below is a posting I've given in the past
            that dealt with this very question. Notice this one function handles
            both the "digits only" condition as well as the general number condition
            via an optional argument that is defaulted to True (check for digits
            only). Of course, setting it to False will do the more general number
            check. I also provided an optional argument to allow leading plus/minus
            signs. The default is False (no sign permitted). Finally, there is an
            optional argument to allow the user to type in the thousands separator
            (also defaulted to False... no thousands separators permitted).

            Rick - MVP

            Those two functions were offered for simplicity sake; but they were
            regionally biased to the US settings. Here is a function, extended to
            allow thousands separators to be entered by the user (although no check
            is made as to their proper placement) which combines the functionality
            of both and removes the regional settings bias. The framework structure
            is there so that the reader can modify the function to allow for other
            things, like a currency symbol, if desired. I know you would be happier
            with deriving the regional decimal point and thousands separator via
            some API calls; but, hey, this is me...<g>

            Function IsNumber(ByVal Value As String, _
            Optional DigitsOnly As Boolean = True, _
            Optional AllowSign As Boolean = False, _
            Optional AllowSeparator As Boolean = False) _
            As Boolean

            Dim DP As String
            Dim TS As String
            If AllowSign Then
            If Value Like "[+-]*" Then Value = Mid$(Value, 2)
            End If
            If AllowSeparator Then
            ' Get local setting for thousands'
            ' separator and eliminate them.
            TS = Mid$(Format$(10 00, "#,###"), 2, 1)
            Value = Replace$(Value, TS, "")
            End If
            If DigitsOnly Then
            IsNumber = Len(Value) > 0 And Not Value Like "*[!0-9]*"
            Else
            ' Get local setting for decimal point
            DP = Format$(0, ".")
            IsNumber = Not Value Like "*[!0-9" & DP & "]*" And _
            Not Value Like "*" & DP & "*" & DP & "*" And _
            Len(Value) > 0 And Value <> DP
            End If

            End Function

            Comment

            Working...