Math with fractions?

  • Thread starter Thread starter Matt R.
  • Start date Start date
M

Matt R.

I'm taking a tire size from one side and the other so for instance, someone
would type in "29 13/16" to represent "twenty-nine inches and thirteen
sixteenths" for the left side and on the other side it would be the same
situation but a different measurement. "32 9/16" to represent "thirty-two
inches and nine sixteenths."

Now with two text boxes populated as:
LFsize = "29 13/16"
RFsize = "32 9/16"

How in the heck do I calculate this to determine the difference and
represent it in fraction format?

Don't say you have to convert the output to decimal because I am trying to
mimick a grossly expensive program and it does this exact thing using
"FileMaker Pro" by cheezy programmers. I am an ASP.NET C# programmer and
never ran across this need before.

Can anybody offer any help? I believe I have to take the input as a string
format and delimit that string into separate integers or such and do the
math, but within VBA I'm lost!
 
Matt

What you are asking for may not be "built-in" in Access. If you have
experience with ASP.Net & C#, I would guess you understand the need for
custom procedures.

Have you tried searching on-line with such keywords as "calculating with
fractions"? Perhaps others have already built such custom procedures...

Or maybe Excel offers such a function ... if so, you could reference the
Excel Object Model and "use" that function.

Good luck

Regards

Jeff Boyce
Microsoft Office/Access MVP
 
Jeff,

Yes, I had to create a custom function. The text has to be entered as a
string type and broken down into an array of numbers. What I was after was
some type of example and the math of which I was looking for would be used as
below.

a/b + c/d = (ad + bc) / bd
-and-
a/b - c/d = (ad - bc) / bd

Anyway, thanks for the help! I figured it out.

Hmm.... Now if only I can simply convert decimal out put of this math to a
fraction. Grrrr.

I knew I had to create a custom function but the thought I was having was
for one why the heck aren't fractions native to Microsoft's business
applications that we use in so many different environments? I guess it's
good they offer VBA capabilities.

Anyway, what I say doesn't matter because no matter who says what, Microsoft
is too big and heartless to listen to their customers.

Thanks Jeff!!!
 
hi Matt,
Now with two text boxes populated as:
LFsize = "29 13/16"
RFsize = "32 9/16"
How in the heck do I calculate this to determine the difference and
represent it in fraction format?
I am an ASP.NET C# programmer and never ran across this need before.
Then the solution should be clear: Implement a class doing the parsing
and the basic arithmetics you need, e.g.:

Option Compare Database
Option Explicit

Public Sub Test()

Dim f1 As clsFractional
Dim f2 As clsFractional

Set f1 = New clsFractional
Set f2 = New clsFractional

f1.FromString "29 13/16"
f2.FromString "32 9/16"

MsgBox f1.ToString() & " - " & _
f2.ToString() & " = " & _
f1.Subtract(f2).ToString() & " (" & _
f1.Subtract(f2).ToDouble() & ")"

End Sub

---

Option Compare Database
Option Explicit

Private m_Integer As Long
Private m_Denominator As Long
Private m_Divisor As Long

Public Property Get IntegerValue() As Long

IntegerValue = m_Integer

End Property

Public Property Get DenominatorValue() As Long

DenominatorValue = m_Denominator

End Property

Public Property Get DivisorValue() As Long

DivisorValue = m_Divisor

End Property

Public Property Let IntegerValue(AValue As Long)

m_Integer = AValue

End Property

Public Property Let DenominatorValue(AValue As Long)

m_Denominator = AValue

End Property

Public Property Let DivisorValue(AValue As Long)

m_Divisor = AValue

End Property

Public Sub FromString(AValue As String)
' Needs correct handling of all possible values.
' This is just the trival parser.

Dim Slash As Long
Dim Space As Long

Slash = InStr(AValue, "/")
Space = InStr(AValue, " ")

m_Integer = CLng(Mid(AValue, 1, Space - 1))
m_Denominator = CLng(Mid(AValue, Space + 1, Slash - Space - 1))
m_Divisor = CLng(Mid(AValue, Slash + 1))

Debug.Print m_Integer; m_Denominator; m_Divisor

End Sub

Public Sub NormalizeFraction()

If Abs(m_Denominator) > m_Divisor Then

m_Integer = Sgn(m_Denominator) * _
(m_Integer + Abs(m_Denominator) \ m_Divisor)
m_Denominator = Abs(m_Denominator) - _
(Abs(m_Denominator) \ m_Divisor) * m_Divisor

End If

End Sub

Public Function Subtract(AValue As clsFractional) As clsFractional
' Trival case, assume same divisor.

Dim Result As clsFractional

Set Result = New clsFractional

Result.DenominatorValue = _
(IntegerValue * DivisorValue + DenominatorValue) - _
(AValue.IntegerValue * AValue.DivisorValue + AValue.DenominatorValue)
Result.DivisorValue = DivisorValue

Set Subtract = Result

End Function

Public Function ToDouble() As Double

Dim Result As Double

Result = m_Integer + m_Denominator / m_Divisor

ToDouble = Result

End Function

Public Function ToString() As String

Dim Result As String

NormalizeFraction
Result = m_Integer & " " & m_Denominator & "/" & m_Divisor

ToString = Result

End Function


If you use this, I strongly encourage you to post your final implementation.

mfG
--> stefan <--
 
Stefan,

I am sure I will eventually implement your solution as mine is quite a bit
messy but I have come up with a very crude but working alternative:

Public Function DecimalToFraction(x)
Dim Temp As String
Dim Fixed As Double

If (VarType(x) < 2) Or (VarType(x) > 6) Then
DecimalToFraction = x
Else
x = Abs(x)
Fixed = Int(x)
If Fixed > 0 Then
Temp = Str(Fixed)
End If
Select Case x - Fixed
Case Is < 0.007813
If Fixed > 0 Then
Temp = Temp
Else
Temp = Str(x)
End If
Case 0.007813 To 0.023438
Temp = Temp + " 1/64"
Case 0.023438 To 0.039063
Temp = Temp + " 1/32"
Case 0.039063 To 0.054688
Temp = Temp + " 3/64"
Case 0.054688 To 0.070313
Temp = Temp + " 1/16"
Case 0.070313 To 0.085938
Temp = Temp + " 5/64"
Case 0.085938 To 0.101563
Temp = Temp + " 3/32"
Case 0.101563 To 0.117188
Temp = Temp + " 7/64"
Case 0.117188 To 0.132813
Temp = Temp + " 1/8"
Case 0.132813 To 0.148438
Temp = Temp + " 9/64"
Case 0.148438 To 0.164063
Temp = Temp + " 5/32"
Case 0.164063 To 0.179688
Temp = Temp + " 11/64"
Case 0.179688 To 0.195313
Temp = Temp + " 3/16"
Case 0.195313 To 0.210938
Temp = Temp + " 13/64"
Case 0.210938 To 0.226563
Temp = Temp + " 7/32"
Case 0.226563 To 0.242188
Temp = Temp + " 15/64"
Case 0.242188 To 0.257813
Temp = Temp + " 1/4"
Case 0.257813 To 0.273438
Temp = Temp + " 17/64"
Case 0.273438 To 0.289063
Temp = Temp + " 9/32"
Case 0.289063 To 0.304688
Temp = Temp + " 19/64"
Case 0.304688 To 0.320313
Temp = Temp + " 5/16"
Case 0.320313 To 0.335938
Temp = Temp + " 21/64"
Case 0.335938 To 0.351563
Temp = Temp + " 11/32"
Case 0.351563 To 0.367188
Temp = Temp + " 23/64"
Case 0.367188 To 0.382813
Temp = Temp + " 3/8"
Case 0.382813 To 0.398438
Temp = Temp + " 25/64"
Case 0.398438 To 0.414063
Temp = Temp + " 13/32"
Case 0.414063 To 0.429688
Temp = Temp + " 27/64"
Case 0.429688 To 0.445313
Temp = Temp + " 7/16"
Case 0.445313 To 0.460938
Temp = Temp + " 29/64"
Case 0.460938 To 0.476563
Temp = Temp + " 15/32"
Case 0.476563 To 0.492188
Temp = Temp + " 31/64"
Case 0.492188 To 0.507813
Temp = Temp + " 1/2"
Case 0.507813 To 0.523438
Temp = Temp + " 33/64"
Case 0.523438 To 0.539063
Temp = Temp + " 17/32"
Case 0.539063 To 0.554688
Temp = Temp + " 35/64"
Case 0.554688 To 0.570313
Temp = Temp + " 9/16"
Case 0.570313 To 0.585938
Temp = Temp + " 37/64"
Case 0.585938 To 0.601563
Temp = Temp + " 19/32"
Case 0.601563 To 0.617188
Temp = Temp + " 39/64"
Case 0.617188 To 0.632813
Temp = Temp + " 5/8"
Case 0.632813 To 0.648438
Temp = Temp + " 41/64"
Case 0.648438 To 0.664063
Temp = Temp + " 21/32"
Case 0.664063 To 0.679688
Temp = Temp + " 43/64"
Case 0.679688 To 0.695313
Temp = Temp + " 11/16"
Case 0.695313 To 0.710938
Temp = Temp + " 45/64"
Case 0.710938 To 0.726563
Temp = Temp + " 23/32"
Case 0.726563 To 0.742188
Temp = Temp + " 47/64"
Case 0.742188 To 0.757813
Temp = Temp + " 3/4"
Case 0.757813 To 0.773438
Temp = Temp + " 49/64"
Case 0.773438 To 0.789063
Temp = Temp + " 25/32"
Case 0.789063 To 0.804688
Temp = Temp + " 51/64"
Case 0.804688 To 0.820313
Temp = Temp + " 13/16"
Case 0.820313 To 0.835938
Temp = Temp + " 53/64"
Case 0.835938 To 0.851563
Temp = Temp + " 27/32"
Case 0.851563 To 0.867188
Temp = Temp + " 55/64"
Case 0.867188 To 0.882813
Temp = Temp + " 7/8"
Case 0.882813 To 0.898438
Temp = Temp + " 57/64"
Case 0.898438 To 0.914063
Temp = Temp + " 29/32"
Case 0.914063 To 0.929688
Temp = Temp + " 59/64"
Case 0.929688 To 0.945313
Temp = Temp + " 15/16"
Case 0.945313 To 0.960938
Temp = Temp + " 61/64"
Case 0.960938 To 0.976563
Temp = Temp + " 31/32"
Case 0.976563 To 0.992188
Temp = Temp + " 63/64"
Case Is > 0.992188
Temp = Str(Int(x) + 1)
End Select

DecimalToFraction = Temp

End If
End Function

Public Function CalcMixedFraction(strMixed As String) As Single
On Error Resume Next
Dim i As Integer

' Declare undimensioned array.
' The Split function will dynamically scope it to 2 elements.
Dim strMyArray() As String

CalcMixedFraction = 0

' This code assumes a hyphen delimiter. If the field contains only a whole
part,
' it will calculate correctly, but if the user enters a whole part, a
space, and the
' fractional part, the function will calculate zero. My preference would
be to use
' the textbox's BeforeUpdate event to ensure the value is in the proper
' format however, if you wish to permit either a hyphen or a space
' delimiter, include the optional code below in your function.

strMyArray = Split(strMixed, "-")
For i = 0 To UBound(strMyArray)
CalcMixedFraction = CalcMixedFraction + Eval(strMyArray(i))
Next i

' Optional code to permit space delimiter
If CalcMixedFraction = 0 Then
strMyArray = Split(strMixed, " ")
For i = 0 To UBound(strMyArray)
CalcMixedFraction = CalcMixedFraction + Eval(strMyArray(i))
Next i
End If
End Function
 
hi Matt,
I am sure I will eventually implement your solution as mine is quite a bit
messy but I have come up with a very crude but working alternative:
It's not necessarily messy. The CalcMixedFraction() function is that
what I called "parser". Then the only thing left is: do you want to do
exact math or not?

If you need exact results than you need to implement a class doing
correct fractional math otherwise you can use your idea.
Public Function DecimalToFraction(x)
End Function
Instead of hardcoding, I would use a function like

http://www.vbforums.com/showthread.php?t=454569
http://www.ozgrid.com/forum/showthread.php?t=22530


mfG
--> stefan <--
 
Back
Top