I do algo to get fraction of number, like get 27/50 with value 0.54
Limit is for x/y, x and y have to be smallest than 10000 to don't have problem
If you arrive to find wrong result, said to me, i try it a lot of time to be sure it's work in all case. Thanks
Code: Select all
Procedure.s Fraction(Valeur.d)
Protected NewList Reste.q()
Protected Entier.q, Numerateur.q, Denominateur.q, Reel.d, Signe.q
Reel.d = Abs(Valeur)
If Reel <> Valeur
Signe = -1
Else
Signe = 1
EndIf
Entier = IntQ(ValD(StrD(Reel, 4)))
; Debug Reel
; Debug Entier
While ValD(StrD(Reel, 4)) <> Entier
AddElement(Reste())
Reste() = Entier
Reel = 1 / (Reel - Entier)
Entier = IntQ(ValD(StrD(Reel, 4)))
; Debug Reel
; Debug Entier
If ListSize(Reste()) > 32 Or Entier > 10000
ProcedureReturn ""
EndIf
Wend
If ListSize(Reste()) = 0
ProcedureReturn ""
EndIf
; Debug ""
Numerateur = Entier
Denominateur = 1
; Debug Str(Numerateur) + "/" + Str(Denominateur)
Repeat
Swap Numerateur, Denominateur
Numerateur = Reste() * Denominateur + Numerateur
; Debug Str(Numerateur) + "/" + Str(Denominateur)
Until PreviousElement(Reste()) = 0
; Debug ""
If ValD(StrD(Valeur - Signe * Numerateur / Denominateur, 12)) = 0 And Numerateur <= 10000 And Denominateur <= 10000 ; And Str(Denominateur) <> LSet("1", Len(Str(Denominateur)), "0")
Debug Str(Signe * Numerateur) + "/" + Str(Denominateur)
ProcedureReturn Str(Signe * Numerateur) + "/" + Str(Denominateur)
Else
ProcedureReturn ""
EndIf
EndProcedure
Debug Fraction(0.154)
Code: Select all
Procedure.s Fraction(Valeur.d)
Protected NewList Reste.q()
Protected Entier.q, Numerateur.q, Denominateur.q, Reel.d, Signe.q
Reel.d = Abs(Valeur)
If Reel <> Valeur
Signe = -1
Else
Signe = 1
EndIf
Entier = IntQ(ValD(StrD(Reel, 4)))
; Debug Reel
; Debug Entier
While ValD(StrD(Reel, 4)) <> Entier
AddElement(Reste())
Reste() = Entier
Reel = 1 / (Reel - Entier)
Entier = IntQ(ValD(StrD(Reel, 4)))
; Debug Reel
; Debug Entier
If ListSize(Reste()) > 32 Or Entier > 10000
ProcedureReturn ""
EndIf
Wend
If ListSize(Reste()) = 0
ProcedureReturn ""
EndIf
; Debug ""
Numerateur = Entier
Denominateur = 1
; Debug Str(Numerateur) + "/" + Str(Denominateur)
Repeat
Swap Numerateur, Denominateur
Numerateur = Reste() * Denominateur + Numerateur
; Debug Str(Numerateur) + "/" + Str(Denominateur)
Until PreviousElement(Reste()) = 0
; Debug ""
If ValD(StrD(Valeur - Signe * Numerateur / Denominateur, 12)) = 0 And Numerateur <= 10000 And Denominateur <= 10000 ; And Str(Denominateur) <> LSet("1", Len(Str(Denominateur)), "0")
Debug Str(Signe * Numerateur) + "/" + Str(Denominateur)
ProcedureReturn Str(Signe * Numerateur) + "/" + Str(Denominateur)
Else
ProcedureReturn ""
EndIf
EndProcedure
Ok = 0
Max = 10000
Temps1 = ElapsedMilliseconds()
For n = 1 To Max
Repeat
Numerateur = Random(9999) + 1
Denominateur = Random(9999) + 1
Until Numerateur % Denominateur <> 0 ; Si la division n'est pas entiere
Debug ""
Debug Str(Numerateur) + "/" + Str(Denominateur)
Reel.d = Numerateur / Denominateur
Texte.s = Fraction(Reel)
If Texte <> ""
Ok + 1
EndIf
Next
Temps2 = ElapsedMilliseconds()
MessageRequester("Fraction", "Result OK : " + Str(Ok) + "/" + Str(Max) + Chr(10) + "Time to convert " + Str(Max) + " values = " + Str(Temps2 - Temps1) + "ms" + Chr(10) + "Time to do 1 converion = " + StrD((Temps2 - Temps1)/Max, 3) + "ms")