% to fraction, is it "possible"? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

% to fraction, is it "possible"?

Post by Krd » 01 Jul 2022, 10:08

Hey,

I have to manually convert e.g 50% to 1/2. Is there a way to do it simpler other than making 1000 if statements like:

Code: Select all

If (Myvar := "50%")
   Myvar := "1/2"
Else if (Myvar := "42,9% ")   ;Same as Excel coverts to fractions. 
 Myvar := "3/7"
ect
This didn't work for me : viewtopic.php?t=994

Or a better way to do it?

User avatar
boiler
Posts: 16931
Joined: 21 Dec 2014, 02:44

Re: % to fraction, is it "possible"?  Topic is solved

Post by boiler » 01 Jul 2022, 10:28

It probably didn't work for you because you didn't convert your strings to a decimal first, like this:

Code: Select all

MsgBox, % Decimal2Fraction(Percent2Decimal("50%"), "D1")
MsgBox, % Decimal2Fraction(Percent2Decimal("42,9% "), "D1")

Percent2Decimal(p) {
	return Trim(StrReplace(StrReplace(p, "%"), ",", ".")) / 100
}
Of course, you need to include the Decimal2Fraction script.

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 01 Jul 2022, 10:54

Many thanks @boiler !

How do I add Myvar to your first line : MsgBox, 42,3% Decimal2Fraction(Percent2Decimal("Myvar"), "D1") as this shows 0.?

Ohhhh, quotes :DDDDD


:bravo:

User avatar
boiler
Posts: 16931
Joined: 21 Dec 2014, 02:44

Re: % to fraction, is it "possible"?

Post by boiler » 01 Jul 2022, 11:48

You wouldn't put 42,3% at the beginning of that line after MsgBox. That % symbol at the beginning of the line has nothing to do with your percentages. Leave it exactly as is. It indicates that what follows is a forced expression. And you would remove the quotation marks around MyVar in the parameter. So it would look like this:

Code: Select all

Myvar := "42,3%"
MsgBox, % Decimal2Fraction(Percent2Decimal(Myvar), "D1")

Or since it looked like you wanted to replace the contents of Myvar:

Code: Select all

Myvar := "42,3%"
Myvar := Decimal2Fraction(Percent2Decimal(Myvar), "D1")
MsgBox, % Myvar

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 01 Jul 2022, 12:29

Much appreciated! :D

I am now getting if Precition and if !Direction have not been assigned a value.
And 4,2% shows 0.

Code: Select all

error at 
	if Precision
		N := Round(N / D * Precision), D := Precision
and

Code: Select all

		if !Direction
		{
			N_Minus := Floor(N), D_Minus := Floor(D), N := Original_N, D := Original_D, Direction := !Direction
			goto Repeat_Reduce

Im totaly green here :D

I changed D to D2 and D3 but still 4,2% shows 0.
Last edited by Krd on 02 Jul 2022, 05:29, edited 1 time in total.

User avatar
boiler
Posts: 16931
Joined: 21 Dec 2014, 02:44

Re: % to fraction, is it "possible"?

Post by boiler » 01 Jul 2022, 13:33

Remove #Warn from your script or put a ; in front of it to comment it out to get rid of the warnings. I can't help with with the results you're getting since you are not showing any part of your script that assigns values to any of those variables.

Also, please post code in code tags like this:
add code tags.png
add code tags.png (14.11 KiB) Viewed 2352 times

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 02 Jul 2022, 05:31

But I like to have warn on to see things that could be wrong.

Here is the full code:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

F12::
MsgBox, % Decimal2Fraction(Percent2Decimal("4,2%"), "D2")     ;Should be 1/24 as Excel shows??
MsgBox, % Decimal2Fraction(Percent2Decimal("42,9%"), "D3")

Percent2Decimal(p) {
	return Trim(StrReplace(StrReplace(p, "%"), ",", ".")) / 100
}

;{[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
}
;}

User avatar
boiler
Posts: 16931
Joined: 21 Dec 2014, 02:44

Re: % to fraction, is it "possible"?

Post by boiler » 02 Jul 2022, 07:42

I’m not going to go through the details of that working code that you copied from someone else and tell you how to get rid of the warnings. If you want to take the time to do that, which generally has no purpose, go ahead. If it says a variable has not been assigned a value, then assign it a null value. Make sure you do it in an appropriate place.

I don’t know why you say it’s returning a value of 0. Did you run the exact script as you’ve shown it? Your comment seems to indicate that it is returning a fraction, although maybe not the most accurate one.

By the way, why add a hotkey to this? Why not just have it run and produce the result?

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 02 Jul 2022, 08:31

I get it :crazy:

I am just testing it and when I put this code to my script for use I get 0, weird. Maybe because the first line is inside another function and the scrip linked is outside...

I have it like this to test if it works first. But it doesn't as excel does. Maybe I will just use excel to convert.



Thanks for your time anyway!

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 14 Jul 2022, 11:35

My problem was the variable which didn't match my statements for further converting to use this code.

This now worked for me with the help from this thread viewtopic.php?f=76&t=106352

Weird enough it seem to work better using what boiler provided even after removing linebreaks and % sign.

Fractions can some times be different that what Excel shows but not a problem for my use in 90% of the time.

User avatar
boiler
Posts: 16931
Joined: 21 Dec 2014, 02:44

Re: % to fraction, is it "possible"?

Post by boiler » 14 Jul 2022, 12:57

Yes, the function I wrote already trimmed spaces and the % sign off, and it handles commas as the separator also, so nothing you were looking to do in that other thread should have been necessary other than removing the linebreak that gets added when you copy from Excel, which this could have been made to take care of also.

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 15 Jul 2022, 02:11

Lol, couldn't read or still can't read RegEx much :D

Seems that you divide then by 100 after trimming? If it is not necessary to trim another time in your function, how to then skip right to dividing? Or add the line break to this trimming instead?

When you have time :)

Rohwedder
Posts: 7630
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: % to fraction, is it "possible"?

Post by Rohwedder » 15 Jul 2022, 04:50

Hallo,
my version:

Code: Select all

q::MsgBox,% Fraction(0.5)
w::MsgBox,% Fraction(4/6 - 15/35 + 1/7)
e::MsgBox,% Fraction(4*Atan(1)) ;PI
Return
Fraction(Number)
{
    SetFormat, FloatFast, 0.15
    a := Number, b := [], Z := [], N := []
    Loop, 9
        b[A_Index] :=  Floor(a), a := 1/(a - b[A_Index])
    Until, Floor(a) > 1.E6
    Z[0] := b[1], Z[-2] := N[-1] := 0, Z[-1] := N[0] := N[-2] := 1
    While, b[1 + I:=A_Index]
        Z[I] := b[I+1]*Z[I-1]+Z[I-2], N[I] := b[I+1]*N[I-1]+N[I-2]
    Return, Z[--I] "/" N[I]
}

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 17 Jul 2022, 13:50

@Rohwedder

Thanks for sharing. As I use percentage and comma, how would you add that to your code?
Or just a number for example:
0,1
5
26
50 = 1/2
48,2
ect


I would like to test your version :D

Rohwedder
Posts: 7630
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: % to fraction, is it "possible"?

Post by Rohwedder » 18 Jul 2022, 02:04

The size of the Precision can be adjusted in Percent2Fraction():

Code: Select all

MsgBox,% Percent2Fraction("50%") ; 1/2
MsgBox,% Percent2Fraction("42,9% ") ; 3/7
MsgBox,% Percent2Fraction("51%") ; 51/100
MsgBox,% Percent2Fraction("52%") ; 13/25
MsgBox,% Percent2Fraction("3%") ; 3/100
MsgBox,% Percent2Fraction("2%") ; 0/1 (rounded to zero)
MsgBox,% Fraction(4*Atan(1), 45) ; 355/113 (usual approximation for PI)

Percent2Fraction(Perc){
	Precision := 45 ;adjustable
	Return, Fraction(Trim(StrReplace(StrReplace(Perc
	,"%"),",","."))/100,Precision)
}
Fraction(Number, Precision:=1.E6){
    SetFormat, FloatFast, 0.15
    a := Number, b := [], Z := [], N := []
    Loop, 9
        b[A_Index] :=  Floor(a), a := 1/(a - b[A_Index])
    Until, Floor(a) > Precision
    Z[0] := b[1], Z[-2] := N[-1] := 0, Z[-1] := N[0] := N[-2] := 1
    While, b[1 + I:=A_Index]
        Z[I] := b[I+1]*Z[I-1]+Z[I-2], N[I] := b[I+1]*N[I-1]+N[I-2]
    Return, Z[--I] "/" N[I]
}

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 18 Jul 2022, 04:31

Okey, many thanks!

I see that it is kinda not possible for me to have it 100% as things mess up when lower percentages. And if that is taken to account then the other parts mess up.

We see this solved as per now. So we will see how it goes :D

Rohwedder
Posts: 7630
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: % to fraction, is it "possible"?

Post by Rohwedder » 18 Jul 2022, 15:51

Only with a table which contains all results that are correct in your opinion is this "100%" possible.
(It is impossible to derive the unrounded value from a rounded one.)
But maybe you like this method?:

Code: Select all

MsgBox,% Percent2Fraction("42,9% ") ; 3/7
MsgBox,% Percent2Fraction("50%") ; 1/2
MsgBox,% Percent2Fraction("51%") ; 51/100
MsgBox,% Percent2Fraction("52%") ; 13/25
MsgBox,% Percent2Fraction("53%") ; 53/100
MsgBox,% Percent2Fraction("1%") ; 1/100
MsgBox,% Percent2Fraction("2%") ; 1/50
MsgBox,% Percent2Fraction("3%") ; 3/100

Percent2Fraction(Perc){
	No := Trim(StrReplace(StrReplace(Perc,"%"),",","."))/100
	A1 := Z1 := N1 := 1
	Loop, 100 ; (Precision = 100)
		IF (A1 > A:=Abs(No-(Z:=Round(No*A_Index))/A_Index))
			A1 := A, Z1 := Z, N1 := A_Index
	Return, Z1 "/" N1
}

Krd
Posts: 405
Joined: 10 Mar 2020, 02:46

Re: % to fraction, is it "possible"?

Post by Krd » 19 Jul 2022, 01:25

Nope, not that method.

I get the percentages from a website and then I have to first convert them to fraction which the website had before.
The company that then receives my data wouldn't want me to use percentages but fractions. Because they use that data to show the results to many more people.

The only 100% match as they want it is to use fractions like Excel does.
But the thing is that lower percentages match 0 which is never true, then I have to adjust fractions in Excel up to two digits. E.g 2% is not 0 nor 2/100 but 1/50. It seems dumb but it is as it is, lol.
If I adjust the D values in the code above then higher percentages mess up to rare big numbers.

It seems that the method I am after when I test in Excel would be:
If percentage doesn't result in 0 then use up to one digit fraction. 50% 1/2.
If percentage matches 0 then another level up one digit to now use up to two digits. 2% is 1/50
I add an image from google to show the menu I refer to.

It looks so simple in Excel but so hard to do as it does :D

If I open and empty Excel file, maybe I could use ComObj to send date, format it and then receive back.

I will test some hundred first and see how big a problem this can be for as it is today.

image.png
image.png (57.68 KiB) Viewed 1055 times

Post Reply

Return to “Ask for Help (v1)”