Version 1.9
This is a function to convert a decimal number into a fraction and return that as a string.
It has options to return an improper fraction or architectural fraction that is in feet and inches.
The architectural option includes zero inches as is the custom in the work that I do but that could be changed or other output formatting options could be added.
Also there is an option to round to the nearest fraction desired.
For example in my circumstances I general round my fractions to the nearest 16th of an inch.
Code: Select all
;{[Function] Decimal2Fraction
; Fanatic Guru
; 2013 12 21
; Version 1.9
;
; Function to Convert a Decimal Number to a Fraction String
;
;------------------------------------------------
;
; Method:
; Decimal2Fraction(Decimal, Options)
;
; Parameters:
; 1) {Decimal} A decimal number to be converted to a fraction string
; 2) {Options ~= {Number}} Round to this fractional Percision ie. 32 would round to the closest 1/32nd
; {Options ~= {D}{Number}} Round fractional to a {Number} limit of digits ie. D5 limits fraction to 5 digits
; {Options ~= "I"} Return Improper Fraction
; {Options ~= "AA"} Return in Architectural format with feet and inches
; {Options ~= "A"} Return in Architectural format with inches only
; Optional
;
;
; Example:
; MsgBox % Decimal2Fraction(1.2345)
; MsgBox % Decimal2Fraction(1.2345,"I")
; MsgBox % Decimal2Fraction(1.2345,"A") ; Convert Decminal Inches to Inches Fraction/Inches"
; MsgBox % Decimal2Fraction(1.2345,"AI") ; Convert Decminal Inches to Fraction/Inches"
; MsgBox % Decimal2Fraction(1.2345,"AA16") ; Convert Decimal Feet to Feet'-Inches Fraction/16th Inches"
; MsgBox % Decimal2Fraction(14.28571428571429,"D5") ; Convert with round to a limit of 5 digit fraction
; MsgBox % Decimal2Fraction(.28571428571429,"AAD5") ; Convert Decimal Feet to Feet'-Inches Fraction/Inches" with round to a limit of 5 digit fraction
Decimal2Fraction(Decimal, Options := "" )
{
FormatFloat := A_FormatFloat
SetFormat, FloatFast, 0.15
Whole := 0
if (Options ~= "i)D")
Digits := RegExReplace(Options,"\D*(\d*)\D*","$1"), (Digits > 15 ? Digits := 15 : )
else
Precision := RegExReplace(Options,"\D*(\d*)\D*","$1")
if (Options ~= "i)AA")
Feet := Floor(Decimal), Decimal -= Feet, Inches := Floor(Decimal * 12), Decimal := Decimal * 12 - Inches
if !(Options ~= "i)I")
Whole := Floor(Decimal), Decimal -= Whole
RegExMatch(Decimal,"^(\d*)\.?(\d*?)0*$",Match), N := Match1 Match2
D := 10 ** StrLen(Match2)
if Precision
N := Round(N / D * Precision), D := Precision
Repeat_Digits:
Original_N := N, Original_D := D
Repeat_Reduce:
X := 0, Temp_D := D
while X != 1
X := GCD(N,D), N := N / X, D := D / X
if Digits
{
if (Temp_D = D and D > 1)
{
if Direction
((N/ D < Decimal) ? N+= 1 : D += 1)
else
((N/ D > Decimal) ? N-= 1 : D -= 1)
goto Repeat_Reduce
}
if !Direction
{
N_Minus := Floor(N), D_Minus := Floor(D), N := Original_N, D := Original_D, Direction := !Direction
goto Repeat_Reduce
}
N_Plus := Floor(N), D_Plus := Floor(D)
if (StrLen(D_Plus) <= Digits and StrLen(D_Minus) > Digits)
N := N_Plus, D := D_Plus
else if (StrLen(D_Minus) <= Digits and StrLen(D_Plus) > Digits)
N := N_Minus, D := D_Minus
else
if (Abs(Decimal - (N_Plus / D_Plus)) < Abs(Decimal - (N_Minus / D_Minus)))
N := N_Plus, D := D_Plus
else
N := N_Minus, D := D_Minus
if (StrLen(D) > Digits)
{
Direction := 0
goto Repeat_Digits
}
}
if (D = 1 and !(Options ~= "i)Inches"))
{
if (Options ~= "i)AA")
{
Inches += N
if (Inches = 12)
Feet ++=, Inches := 0
}
else
Whole += N
N := 0
}
N := Floor(N)
D := Floor(D)
if (Options ~= "i)AA")
Output := Feet "'-" Inches (N and D ? " " N "/" D:"")""""
else
Output := (Whole ? Whole " ":"") (N and D ? N "/" D:"")((Options ~= "i)A") ? """":"")
SetFormat, FloatFast, %FormatFloat%
return (Whole + N ? Trim(Output) : 0)
}
GCD(A, B)
{
while B
B := Mod(A|0x0, A:=B)
return A
}
;}
[Function] Fraction2Decimal
Version 1.6
This is a function to convert a fraction string to decimal. It tries to account for things like spaces and - ' " in the fraction. It can handle a robust combinations of feet, inches and decimals.
Like: 6 feet 9.5" and 1.5 of 3 inches
It expects something more normal like this though: 6'-8 3/8"
Code: Select all
;{[Function] Fraction2Decimal
; Fanatic Guru
; 2013 12 18
; Version 1.6
;
; Function to Fraction String to a Decimal Number
; Tries to account for any phrasing of feet and inches
;------------------------------------------------
;
; Method:
; Fraction2Decimal(Fraction, Unit)
;
; Parameters:
; 1) {Fraction} A string representing a fraction to be converted to a decimal number
; 2) {Unit} = true Include feet or inch symbol in return
; {Unit} = false Do not include feet or inch symbol in return
; Optional - Default to false
;
; Example:
; MsgBox % Fraction2Decimal("7/8")
; MsgBox % Fraction2Decimal("1 7/8")
; MsgBox % Fraction2Decimal("1-7/8""") ; "" required to escape a literal " for testing
; MsgBox % Fraction2Decimal("2'1-7/8""") ; "" required to escape a literal " for testing
; MsgBox % Fraction2Decimal("2'-1 7/8""") ; "" required to escape a literal " for testing
; MsgBox % Fraction2Decimal("2' 1"" 7/8") ; "" required to escape a literal " for testing
;
Fraction2Decimal(Fraction, Unit := false)
{
FormatFloat := A_FormatFloat
SetFormat, FloatFast, 0.15
Num := {}
N := 0
D := 1
if RegExMatch(Fraction, "^\s*-")
Has_Neg := true
if RegExMatch(Fraction, "i)feet|foot|ft|'")
Has_Feet := true
if RegExMatch(Fraction, "i)inch|in|""")
Has_Inches := true
if RegExMatch(Fraction, "i)/|of|div")
Has_Fraction := true
Output := Trim(Fraction,"""'")
if Output is number
{
SetFormat, FloatFast, %FormatFloat%
return Output (Unit ? (Has_Feet ? "'":(Has_Inches ? """":"")) : "")
}
RegExMatch(Fraction,"^[^\d\.]*([\d\.]*)[^\d\.]*([\d\.]*)[^\d\.]*([\d\.]*)[^\d\.]*([\d\.]*)",Match)
Loop 4
if !(Match%A_Index% = "")
Num.Insert(Match%A_Index%)
if Has_Fraction
{
N := Num[Num.MaxIndex()-1]
D := Num[Num.MaxIndex()]
}
Output := (Num.MaxIndex() = 2 ? N / D : (Num[1]) + N / D)
if (Has_Feet & Has_Inches)
if (Num.MaxIndex() = 2)
Output := Num[1] + Num[2] /12
else
Output := Num[1] + ((Num.MaxIndex() = 3 ? 0:Num[2]) + N / D) / 12
Output := (Has_Neg ? "-":"") (Output ~= "." ? RTrim(RTrim(Output,"0"),".") : Output) (Unit ? (Has_Feet ? "'":(Has_Inches ? """":"")) : "")
SetFormat, FloatFast, %FormatFloat%
return Output
}
;}
Highlighted to Fraction
Version 1.6
Here is a script that uses the two above functions to take what is highlighted and convert it to a fraction. It has 4 hotkeys that output different formats.
Win+F . . . . . . . . . . Decimal or Fraction to Proper Fraction
Win+Ctrl+F . . . . . . Decimal or Fraction to Improper Fraction
Win+Alt+F . . . . . . . Decimal or Fraction to Architectural with a Precision of 1/16th inch
Win+Ctrl+Alt+F . . . Decimal or Fraction to Custom Format based on GUI input
It can also be used to convert fractions to different format fractions. Through the GUI you can also convert highlighted fractions to decimal.
Code: Select all
;{Highlighted to Fraction
; Fanatic Guru
; 2013 12 18
; Version 1.6
;
; Use Clipboard to Convert Highlighted Number to Fraction Format
; Number can be a decimal or decimal with a ' or " for feet and inches
; Number can be a fraction, proper or improper
; Number can be a robust combination of ' feet foot ft " inch in / of etc. and decimals
;
;}
; INITIALIZATION - ENVIROMENT
;{-----------------------------------------------
;
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#SingleInstance force ; Ensures that only the last executed instance of script is running
;}
; INITIALIZATION - VARIABLES
;{-----------------------------------------------
;
Precision := 256
;}
; INITIALIZATION - GUI
;{-----------------------------------------------
;
Gui, Add, Text,, Highlighted to Convert
Gui, Add, Edit, ReadOnly W210 vGuiHigh, %GuiHigh%
Gui, Add, Text, yp+30, Fraction Precision
Gui, Add, Edit, W80 vPrecision, %Precision%
Gui, Add, Radio, xp+100 yp-8 vRound Checked, 1/N
Gui, Add, Radio, yp+15, N Digits
Gui, Add, Radio, Xm yp+30 Group vStyle Checked, Proper Fraction
Gui, Add, Radio,, Improper Fraction
Gui, Add, Radio,, Architectural Feet and Inches
Gui, Add, Radio,, Architectural Inches Only
Gui, Add, Radio, yp+24, Convert to Decimal
Gui, Add, Button, yp+24 X40 W120 H30 Default, Convert
GuiControl, Focus, Style
;}
; HOTKEYS
;{-----------------------------------------------
;
#f:: ;{ <-- Decimal or Fraction to Proper Fraction
Style := 1
gosub Clip_Convert
return
;}
#^f:: ;{ <-- Decimal or Fraction to Improper Fraction
Style := 2
gosub Clip_Convert
return
;}
#!f:: ;{ <-- Decimal or Fraction to Architectural - Feet and Inches
Style := 3
gosub Clip_Convert
return
;}
#^!f:: ;{ <-- Decimal or Fraction to Custom Fraction Format
Clipboard := ""
Send ^c
ClipWait,.5
GuiControl,, GuiHigh, %Clipboard%
Gui, Show, AutoSize, Highlighted to Fraction
return
;}
;}
; SUBROUTINES
;{-----------------------------------------------
;
Clip_Convert:
Clipboard := ""
Send ^c
ClipWait,.5
Convert:
D := Fraction2Decimal(Clipboard,1)
Dec_Feet := true
Dec_Inch := false
if InStr(D, """")
Dec_Inch := true, Dec_Feet := false
X := RTrim(D, "'""")
if Style = 1
Clipboard := Decimal2Fraction((Dec_Inch ? X/12 : X),(Precision ? (Round = 2 ? "D":"") Precision:""))
if Style = 2
Clipboard := Decimal2Fraction((Dec_Inch ? X/12 : X),"I"(Precision ? (Round = 2 ? "D":"") Precision:""))
if Style = 3
Clipboard := Decimal2Fraction((Dec_Inch ? X/12 : X),"AA"(Precision ? (Round = 2 ? "D":"") Precision:""))
if Style = 4
Clipboard := Decimal2Fraction((Dec_Feet ? X*12 : X),"A"(Precision ? (Round = 2 ? "D":"") Precision:""))
if Style = 5
Clipboard := D
Send ^v
return
;}
; SUBROUTINES - GUI
;{-----------------------------------------------
;
GuiClose:
GuiEscape:
Gui, Hide
return
ButtonConvert:
Gui, Submit
gosub Convert
return
;}
; FUNCTIONS
;{-----------------------------------------------
;
#Include [Function] Decimal2Fraction.ahk
#Include [Function] Fraction2Decimal.ahk
;}