-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathDecimal2Fraction.ahk
182 lines (177 loc) · 5.64 KB
/
Decimal2Fraction.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
;{[Function] Decimal2Fraction and Fraction2Decimal
; 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)
}
;{[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
}
GCD(A, B)
{
while B
B := Mod(A|0x0, A:=B)
return A
}