
par contre le code (1° du post) du haut me renvois rien :/
Code : Tout sélectionner
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", "Détermination bonne : " + Str(Ok) + "/" + Str(Max) + Chr(10) + "Temps d'analyse de " + Str(Max) + " valeurs = " + Str(Temps2 - Temps1) + "ms" + Chr(10) + "Temps d'analyse moyen = " + StrD((Temps2 - Temps1)/Max, 3) + "ms")
Code : Tout sélectionner
Structure Fraction
numerator.i
denominator.i
EndStructure
Procedure trouverFraction(valeur.d, nbMotif.l, *fraction.Fraction)
numerator = Pow(10, nbMotif)*valeur - valeur
denominator = Pow(10, nbMotif)-1
*fraction\numerator = numerator
*fraction\denominator = denominator
EndProcedure
frac.Fraction
trouverFraction(1.444, 1, @frac)
Debug Str(frac\numerator) + "/" + Str(frac\denominator)
trouverFraction(3.143143, 3, @frac)
Debug Str(frac\numerator) + "/" + Str(frac\denominator)
Code : Tout sélectionner
Structure Fraction
numerator.i
denominator.i
EndStructure
Procedure PGCD(Value1, Value2)
pgdc = 0
If Value1 = 0 Or Value2 = 0
ProcedureReturn 1
EndIf
If Value1 < Value2
Val = Value1
Value1 = Value2
Value2 = Val
EndIf
If Value1%Value2 = 0
pgcd = Value1/Value2
Else
Dividende = Value1
Diviseur = Value2
Reste = 0
Reste1 = 0
Repeat
Reste1 = Dividende%Diviseur
If Reste1 = 0
pgcd = Reste
Else
Reste = Reste1
EndIf
Dividende = Diviseur
Diviseur = Reste
Until Reste1 = 0
EndIf
ProcedureReturn pgcd
EndProcedure
Procedure findFraction(value.d, *fraction.Fraction)
str.s = StrD(value, 14)
;suppression des zeros
While Right(str, 1) = "0"
str = Left(str, Len(str)-1)
Wend
nbDec = Len(str)-FindString(str, ".", 1)
;repérage d'un motif répétitif
For motifSize=1 To nbDec
motif.s = Right(str, motifSize)
nbMotif = 0
i = Len(str) - motifSize + 1
While Mid(str, i, motifSize) = motif And i>0
i - motifSize
nbMotif + 1
Wend
If nbMotif >= 2
Break
EndIf
Next
If motifSize > nbDec
motifSize = nbDec
EndIf
;coeff sert à mettre à la partie entière tout ce qui n'est pas identique au motif
;par exemple: 8.62121 deviendra 86.2121 (le motif est 21)
coeff = Pow(10, nbDec - nbMotif*motifSize)
coeff2 = Pow(10, nbMotif)
numerator = Int(value * coeff * coeff2) - Int(value*coeff)
denominator = (coeff2 - 1) * coeff
;simplification de la fraction
pgcd = PGCD(numerator, denominator)
numerator = numerator / pgcd
denominator = denominator / pgcd
*fraction\numerator = numerator
*fraction\denominator = denominator
EndProcedure
frac.Fraction
findFraction(1.333, @frac)
Debug Str(frac\numerator) + "/" + Str(frac\denominator)