By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,853 Members | 1,570 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,853 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
Share this Question
Share on Google+
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" <ri************@NOSPAMcomcast.net> 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" <no*************@comcast.net> wrote in message
news:X_********************@comcast.com...

"Rick Rothstein" <ri************@NOSPAMcomcast.net> 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" <ri************@NOSPAMcomcast.net> 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.<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$(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.