448,933 Members | 1,697 Online
Need help? Post your question and get tips & solutions from a community of 448,933 IT Pros & Developers. It's quick & easy.

# decimal to fraction

 P: n/a 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 Jul 17 '05 #1
5 Replies

 P: n/a > 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 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 Jul 17 '05 #2

 P: n/a "Rick Rothstein" wrote in message news:24********************@comcast.com... 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 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(WholeNumber) 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. Jul 17 '05 #3

 P: n/a "Steve Gerrard" wrote in message news:X_********************@comcast.com... "Rick Rothstein" wrote in message news:24********************@comcast.com... 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 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(WholeNumber) Else... 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(Denominator * _ Abs(DecimalNumber - 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(ByVal DecimalNumber As Variant, _ Optional ByVal LargestDenominator 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(DecimalNumber) Then DecimalNumber = CDbl(DecimalNumber) WholeNumber = Fix(DecimalNumber) Denominator = LargestDenominator Numerator = Format(Denominator * _ Abs(DecimalNumber - WholeNumber), "0") If Numerator = Denominator Then Numerator = 0 WholeNumber = WholeNumber + 1 End If If Numerator Then GCD = LargestDenominator TopNumber = Numerator Do Remainder = (GCD Mod TopNumber) GCD = TopNumber TopNumber = Remainder Loop Until Remainder = 0 Numerator = Numerator \ GCD Denominator = Denominator \ GCD MakeFraction = CStr(WholeNumber) & _ IIf(bShowDash, "-", " ") & _ CStr(Numerator) & "/" & _ CStr(Denominator) Else MakeFraction = CStr(WholeNumber) 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 Jul 17 '05 #4

 P: n/a "Rick Rothstein" wrote in message news:PN********************@comcast.com... http://vbnet.mvps.org/code/helpers/numbertofraction.htm. 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? 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. Jul 17 '05 #5

 P: n/a > 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, ",", "") 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. If Value Like "[\$]*" Then Value = Mid\$(Value, 2) 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) Can you make a locale independent version of IsNumber? I don't need it, but some users might. Your wish is my command. 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... 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\$(1000, "#,###"), 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 Jul 17 '05 #6

### This discussion thread is closed

Replies have been disabled for this discussion.