Fraction Format

N

Nando

I need to store some information in my database in fractions. And I need to
make some basic operations with it (sum, product).

Example:

2 1/2
3 1/4
4 1/8
5 1/16

Can somebody help me?
 
N

Nando

I could, but I need to print reports showing the fractions. People at
purchase dept & shop are used to see dimensions in imperial system: 2’ 3 ¼â€.
 
R

Roger Carlson

OK, I'll make the assumption that for some reason you MUST store the data in
this format. If that is true, then the datatype must be Text. Therefore,
you need to convert your text to it's equivalent decimal format. I will
further assume that the number will ALWAYS have a (1) space between the
integer and the fraction.

In a General Module, create the following function:

Function ConvertTextToDecimal(TextNumber As String) as Double
Dim IntegerPortion As String
Dim Fraction As String
IntegerPortion = Left(TextNumber, InStr(TextNumber, " ") - 1)
Fraction = Mid(TextNumber, InStr(TextNumber, " "))
ConvertTextToDecimal = Eval(IntegerPortion) + Eval(Fraction)
End Function

To use it, you would use ConvertTextToDecimal(<fieldname>) instead of using
just the <fieldname>.

--
--Roger Carlson
MS Access MVP
Access Database Samples: www.rogersaccesslibrary.com
Want answers to your Access questions in your Email?
Free subscription:
http://peach.ease.lsoft.com/scripts/wa.exe?SUBED1=ACCESS-L
 
R

Roger Carlson

W

Wayne-in-Manchester

Sorry to say that if you want to use the number in ANY form of numerical
function 1+2=3 etc then the answer has to be no you can't.

Basically access will display anything you want it to as text but you can't
use text in a numerical function - which is what I think you're after.

You can write some simply code that will change the text back into numbers
that can be used but this isn't what your looking for I think.

Sorry
 
J

James A. Fortune

Nando said:
I need to store some information in my database in fractions. And I need to
make some basic operations with it (sum, product).

Example:

2 1/2
3 1/4
4 1/8
5 1/16

Can somebody help me?

This problem is much trickier than it appears. I would start by
breaking up your mixed fractions into separate fields.

IPart Numerator Denominator
2 1 2
3 1 4
4 1 8
5 1 16

M1 = IPart1 + Numerator1 / Denominator1
M2 = IPart2 + Numerator2 / Denominator2

Sum:
(A + B / C) + (D + E / F) = A + D + (BF + CE) / CF
= (ACF + DCF + BF + CE) / CF

Product:

(A + B / C) * (D + E / F) = AD + BD / C + AE / F + BE / CF
= (ADCF + BDF + ACE + BE) / CF

Then you need a table of prime numbers along with a means to obtain the
prime factorization. Note that you only need to check for prime factors
that are less than or equal to the square root of the number. But wait.
After cancelling common prime factors (using the exponents), and using
the Mod and Int functions to obtain the separate pieces for the
resulting mixed fraction you discover a problem. When two numbers that
are relatively prime are divided, is the residue also relatively prime? No.

(2^2 * 5 * 9) / (3 * 7) = 180 / 21 = 8 + 12 / 21.

Therefore you would need to reduce the resulting fraction again.

8 4 7

So, the way to do it is to break the Sum or Product numerator and
denominator into a mixed fraction first, then do the prime factorization
on the resulting fraction.

'Begin Module "Air Code" --------
Type MixedFraction
IPart As Long
FPart As Fraction
End Type

Type Fraction
Numerator As Long
Denominator As Long
End Type

Public Function MixedFractionSum(M1 As MixedFraction, M2 As
MixedFraction) As MixedFraction
Dim dblMax As Double
Dim dblNumerator As Double
Dim dblDenominator As Double
Dim SumFraction As Fraction

dblMax = CDbl(2147483647)
'(ACF + DCF + BF + CE) / CF

'Check for overflow (ignore max negative case)
If Abs(CDbl(M1.IPart) * M1.Denominator * M2.Denominator + ... +
M1.Denominator * M2.Numerator) > dblMax Then ...
dblNumerator = Int(M1.IPart * M1.Denominator * M2.Denominator + ...
dblDenominator = M1.Denominator * M2.Denominator
MixedFractionSum.IPart = Int(dblNumerator / dblDenominator)
SumFraction.Numerator = dblNumerator - dblDenominator *
MixedFractionSum.IPart
SumFraction.Denominator = dblDenominator
MixedFractionSum.FPart = SumFraction
End Function

Public Sub MixedFractionProduct(M1 As MixedFraction, M2 As
MixedFraction)) As MixedFraction
Dim dblMax As Double
Dim dblNumerator As Double
Dim dblDenominator As Double
Dim ProductFraction As Fraction

dblMax = CDbl(2147483647)
'(ADCF + BDF + ACE + BE) / CF

'Check for overflow (ignore max negative case)
If Abs(CDbl(M1.IPart) * M2.IPart * M1.Denominator * M2.Denominator + ...
+ M1.Numerator * M2.Numerator) > dblMax Then ...
dblNumerator = Int(M1.IPart * M1.Denominator * M2.Denominator + ...
dblDenominator = M1.Denominator * M2.Denominator
MixedFractionSum.IPart = Int(dblNumerator / dblDenominator)
dblNumerator = dblNumerator - dblDenominator * MixedFractionSum.IPart
ProductFraction.Numerator = dblNumerator
ProductFraction.Denominator = dblDenominator
MixedFractionSum.FPart = ReduceFraction(MyFraction)
Public Function

ReduceFraction(F1 As Fraction) As Fraction
'Some tricky code that interacts with tblPrimeNumbers
End Function
'End Module "Air Code" --------

'Code behind form:

Dim M1 As MixedFraction
Dim M2 As MixedFraction
Dim MSumResult As MixedFraction
Dim MProductResult As MixedFraction
Dim MFraction As Fraction

M1.IPart = 4
MFraction.Numerator = 1
MFraction.Denominator = 8
M1.FPart = MFraction
M2.IPart = 3
MFraction.Numerator = 1
MFraction.Denominator = 4
M2.FPart = MFraction

MSumResult = MixedFractionSum(M1, M2)
MProductResult = MixedFractionProduct(M1, M2)

MsgBox(MSumResult.IPart)
MsgBox(MSumResult.FPart.Numerator)
MsgBox(MSumResult.FPart.Denominator)

From your example I assumed that the fractions do not have very large
numerators or denominators. Obviously, the overflow provisions are
incomplete. Maybe this example will form the basis for a satisfactory
solution.

James A. Fortune
[email protected]
 
A

Arvin Meyer [MVP]

Nando said:
I need to store some information in my database in fractions. And I need to
make some basic operations with it (sum, product).

Example:

2 1/2
3 1/4
4 1/8
5 1/16

Can somebody help me?

Store your data as a Double and display it in a report as a fraction. Use
this function to convert in the report or call it in a query:

Public Function FractionIt(dblNumIn As Double) As String
'========================================================
' Name: FractionIt
' Purpose: Converts a double into a string representing a rounded fraction
' Inputs: dblNumIn As Double
' Returns: String
' Author: Arvin Meyer
' Date: Revised - 6/22/2001
' Comment: Rounds down from 1/64 over
'========================================================
On Error GoTo Err_FractionIt

Dim strFrac As String
Dim strSign As String
Dim strWholeNum As String
Dim dblRem As Double

If dblNumIn < 0 Then
strSign = "-"
dblNumIn = dblNumIn * -1
Else
strSign = " "
End If

strWholeNum = Fix([dblNumIn])

dblRem = [dblNumIn] - [strWholeNum]

Select Case dblRem
Case 0
strFrac = ""
Case Is < 0.046875
strFrac = "1/32"
Case Is < 0.078125
strFrac = "1/16"
Case Is < 0.109375
strFrac = "3/32"
Case Is < 0.140625
strFrac = "1/8"
Case Is < 0.171875
strFrac = "5/32"
Case Is < 0.203125
strFrac = "3/16"
Case Is < 0.234375
strFrac = "7/32"
Case Is < 0.265625
strFrac = "1/4"
Case Is < 0.296875
strFrac = "9/32"
Case Is < 0.328125
strFrac = "5/16"
Case Is < 0.359375
strFrac = "11/32"
Case Is < 0.390625
strFrac = "3/8"
Case Is < 0.421875
strFrac = "13/32"
Case Is < 0.453125
strFrac = "7/16"
Case Is < 0.484375
strFrac = "15/32"
Case Is < 0.515625
strFrac = "1/2"
Case Is < 0.546875
strFrac = "17/32"
Case Is < 0.578125
strFrac = "9/16"
Case Is < 0.609375
strFrac = "19/32"
Case Is < 0.640625
strFrac = "5/8"
Case Is < 0.671875
strFrac = "21/32"
Case Is < 0.703125
strFrac = "11/16"
Case Is < 0.734375
strFrac = "23/32"
Case Is < 0.765625
strFrac = "3/4"
Case Is < 0.796875
strFrac = "25/32"
Case Is < 0.828125
strFrac = "13/16"
Case Is < 0.859375
strFrac = "27/32"
Case Is < 0.890625
strFrac = "7/8"
Case Is < 0.921875
strFrac = "29/32"
Case Is < 0.953125
strFrac = "15/16"
Case Is < 0.984375
strFrac = "31/32"
Case Is < 1
strFrac = "1"
End Select

If strFrac = "1" Then
FractionIt = strSign & (strWholeNum + 1)
Else
FractionIt = strSign & strWholeNum & " " & strFrac
End If

Exit_FractionIt:
Exit Function

Err_FractionIt:
Select Case Err
Case 0

Case Else
MsgBox Err.Description
Resume Exit_FractionIt
End Select

End Function
--
Arvin Meyer, MCP, MVP
Microsoft Access
Free Access downloads
http://www.datastrat.com
http://www.mvps.org/access
 
Z

ZigZagZak

This code actually has a small problem to it. I have used it for a couple
weeks and kept noticing that when its used in a string it kept putting a
space after the whole number if strfrac = "" . After looking at it for a
couple minutes I found the problem. I added another If/Then statment to the
bottom. The new code is :

Public Function FractionIt(dblNumIn As Double) As String
'========================================================
' Name: FractionIt
' Purpose: Converts a double into a string representing a rounded fraction
' Inputs: dblNumIn As Double
' Returns: String
' Author: Arvin Meyer
' Date: Revised - 6/22/2001
' Comment: Rounds down from 1/64 over
'========================================================
On Error GoTo Err_FractionIt

Dim strFrac As String
Dim strSign As String
Dim strWholeNum As String
Dim dblRem As Double

If dblNumIn < 0 Then
strSign = "-"
dblNumIn = dblNumIn * -1
Else
strSign = " "
End If

strWholeNum = Fix([dblNumIn])

dblRem = [dblNumIn] - [strWholeNum]

Select Case dblRem
Case 0
strFrac = ""
Case Is < 0.046875
strFrac = "1/32"
Case Is < 0.078125
strFrac = "1/16"
Case Is < 0.109375
strFrac = "3/32"
Case Is < 0.140625
strFrac = "1/8"
Case Is < 0.171875
strFrac = "5/32"
Case Is < 0.203125
strFrac = "3/16"
Case Is < 0.234375
strFrac = "7/32"
Case Is < 0.265625
strFrac = "1/4"
Case Is < 0.296875
strFrac = "9/32"
Case Is < 0.328125
strFrac = "5/16"
Case Is < 0.359375
strFrac = "11/32"
Case Is < 0.390625
strFrac = "3/8"
Case Is < 0.421875
strFrac = "13/32"
Case Is < 0.453125
strFrac = "7/16"
Case Is < 0.484375
strFrac = "15/32"
Case Is < 0.515625
strFrac = "1/2"
Case Is < 0.546875
strFrac = "17/32"
Case Is < 0.578125
strFrac = "9/16"
Case Is < 0.609375
strFrac = "19/32"
Case Is < 0.640625
strFrac = "5/8"
Case Is < 0.671875
strFrac = "21/32"
Case Is < 0.703125
strFrac = "11/16"
Case Is < 0.734375
strFrac = "23/32"
Case Is < 0.765625
strFrac = "3/4"
Case Is < 0.796875
strFrac = "25/32"
Case Is < 0.828125
strFrac = "13/16"
Case Is < 0.859375
strFrac = "27/32"
Case Is < 0.890625
strFrac = "7/8"
Case Is < 0.921875
strFrac = "29/32"
Case Is < 0.953125
strFrac = "15/16"
Case Is < 0.984375
strFrac = "31/32"
Case Is < 1
strFrac = "1"
End Select

If strFrac = "1" Then
FractionIt = strSign & (strWholeNum + 1)
End If
If strFrac = "" Then
FractionIt = strSign & strWholeNum
End If
If strFrac <> "1" And strFrac <> "" Then
FractionIt = strSign & strWholeNum & " " & strFrac
End If

Exit_FractionIt:
Exit Function

Err_FractionIt:
Select Case Err
Case 0

Case Else
MsgBox Err.Description
Resume Exit_FractionIt
End Select

End Function




Arvin Meyer said:
Nando said:
I need to store some information in my database in fractions. And I need to
make some basic operations with it (sum, product).

Example:

2 1/2
3 1/4
4 1/8
5 1/16

Can somebody help me?

Store your data as a Double and display it in a report as a fraction. Use
this function to convert in the report or call it in a query:

Public Function FractionIt(dblNumIn As Double) As String
'========================================================
' Name: FractionIt
' Purpose: Converts a double into a string representing a rounded fraction
' Inputs: dblNumIn As Double
' Returns: String
' Author: Arvin Meyer
' Date: Revised - 6/22/2001
' Comment: Rounds down from 1/64 over
'========================================================
On Error GoTo Err_FractionIt

Dim strFrac As String
Dim strSign As String
Dim strWholeNum As String
Dim dblRem As Double

If dblNumIn < 0 Then
strSign = "-"
dblNumIn = dblNumIn * -1
Else
strSign = " "
End If

strWholeNum = Fix([dblNumIn])

dblRem = [dblNumIn] - [strWholeNum]

Select Case dblRem
Case 0
strFrac = ""
Case Is < 0.046875
strFrac = "1/32"
Case Is < 0.078125
strFrac = "1/16"
Case Is < 0.109375
strFrac = "3/32"
Case Is < 0.140625
strFrac = "1/8"
Case Is < 0.171875
strFrac = "5/32"
Case Is < 0.203125
strFrac = "3/16"
Case Is < 0.234375
strFrac = "7/32"
Case Is < 0.265625
strFrac = "1/4"
Case Is < 0.296875
strFrac = "9/32"
Case Is < 0.328125
strFrac = "5/16"
Case Is < 0.359375
strFrac = "11/32"
Case Is < 0.390625
strFrac = "3/8"
Case Is < 0.421875
strFrac = "13/32"
Case Is < 0.453125
strFrac = "7/16"
Case Is < 0.484375
strFrac = "15/32"
Case Is < 0.515625
strFrac = "1/2"
Case Is < 0.546875
strFrac = "17/32"
Case Is < 0.578125
strFrac = "9/16"
Case Is < 0.609375
strFrac = "19/32"
Case Is < 0.640625
strFrac = "5/8"
Case Is < 0.671875
strFrac = "21/32"
Case Is < 0.703125
strFrac = "11/16"
Case Is < 0.734375
strFrac = "23/32"
Case Is < 0.765625
strFrac = "3/4"
Case Is < 0.796875
strFrac = "25/32"
Case Is < 0.828125
strFrac = "13/16"
Case Is < 0.859375
strFrac = "27/32"
Case Is < 0.890625
strFrac = "7/8"
Case Is < 0.921875
strFrac = "29/32"
Case Is < 0.953125
strFrac = "15/16"
Case Is < 0.984375
strFrac = "31/32"
Case Is < 1
strFrac = "1"
End Select

If strFrac = "1" Then
FractionIt = strSign & (strWholeNum + 1)
Else
FractionIt = strSign & strWholeNum & " " & strFrac
End If

Exit_FractionIt:
Exit Function

Err_FractionIt:
Select Case Err
Case 0

Case Else
MsgBox Err.Description
Resume Exit_FractionIt
End Select

End Function
--
Arvin Meyer, MCP, MVP
Microsoft Access
Free Access downloads
http://www.datastrat.com
http://www.mvps.org/access
 
Top