Petit problème de Float

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Torp
Messages : 360
Inscription : lun. 22/nov./2004 13:05

Petit problème de Float

Message par Torp »

Voici un petit exemple de mon souci :

Code : Tout sélectionner

a.f = 21.3
b.f = 2.65
c.f = a-2*b

d.f = 16.0

If c = d
	Debug "égal"
ElseIf d < c
	Debug "inférieur"
ElseIf d > c
	Debug "supérieur"
EndIf
Le résultat devrait être "égal" mais ce n'est pas le cas... Comment puis-je contourner cette limitation "informatique" de manière simple et fiable ?

Merci,
Bye
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Petit problème de Float

Message par graph100 »

utilise des double : .d

et c'est normal qu'avec des float ce ne soit pas égal. (lit l'aide de PB dans la section "Variables, Types et Opérateurs"
Il vaudrait mieux ne jamais faire des tests d'égalité avec des nombres à virgule.
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Petit problème de Float

Message par Ar-S »

Tu peux éventuellement fixer le nombre de décimale.

Code : Tout sélectionner

a.f = 21.3
b.f = 2.65
c.f = a-2*b

d.f = 16.0

Fixed_c.f = StrF(c,5)
Fixed_d.f = StrF(d,5)

If Fixed_c = Fixed_d
		Debug "égal"
ElseIf Fixed_c > Fixed_d
		Debug "supérieur"
ElseIf Fixed_c < Fixed_d
		Debug "Inferieur"
EndIf

------edit-----

La remarque de graph100 me parait plus censée
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
GallyHC
Messages : 1708
Inscription : lun. 17/déc./2007 12:44

Re: Petit problème de Float

Message par GallyHC »

Ouep j'ai testé avec ce que disait "graph100" et cela fonctionne, voir l'exemple :

Code : Tout sélectionner

a.d = 21.3
b.d = 2.65
c.d = a - (2 * b)

d.f = 16.0

If c = d
   Debug "égal"
ElseIf d < c
   Debug "inférieur"
ElseIf d > c
   Debug "supérieur"
EndIf
Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Fred
Site Admin
Messages : 2809
Inscription : mer. 21/janv./2004 11:03

Re: Petit problème de Float

Message par Fred »

C'est parce que c'est pas égal, tout simplement :)

Code : Tout sélectionner

a.f = 21.3
b.f = 2.65
c.f = a-2*b

d.f = 16.0

Debug c
Debug d
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Petit problème de Float

Message par graph100 »

Fred a écrit :C'est parce que c'est pas égal, tout simplement :)

Code : Tout sélectionner

a.f = 21.3
b.f = 2.65
c.f = a-2*b

d.f = 16.0

Debug c
Debug d
Eh oui, mais pour le comprendre il faut qu'il lise cette page de l'aide de PureBasic (tout en bas) :D

@GallyHC : j'avais testé quand même :mrgreen:
@Ar-S : Ta méthode fonctionne, mais je pense qu'il serait plus adéquate de mettre un intervalle plutôt que de passer par des string

Tiens, je me suis amusé à comparer les vitesses d'exécutions entre les différentes méthodes.
Conclusion (sans faire de tests ANOVA) : l'utilisation de chaine est 1000 fois plus lente que les méthodes numériques.
Mais entre les autres méthodes, il n'apparait pas de différences significatives.
Ma préférence irai vers la macro avec ABS()

Code : Tout sélectionner

DisableDebugger
_Debug$ = ""

Macro IS_EGAL(nb1, nb2, intervalle)
	(Abs(nb1 - nb2) <= intervalle * 1.1)
EndMacro

Macro IS_EGAL1(nb1, nb2, intervalle)
	(nb1 - intervalle <= nb2) And (nb1 + intervalle >= nb2)
EndMacro

Macro IS_EGAL_STRING(nb1, nb2, nb_dec)
	StrF(nb1, nb_dec) = StrF(nb2, nb_dec)
EndMacro


a.f = 21.3
b.f = 2.65
c.f = a-2*b

d.f = 16.0

_Debug$ + #CR$ + StrF(c)
_Debug$ + #CR$ + StrF(d)

If IS_EGAL(c, d, 0.01)
	_Debug$ + #CR$ + "EGAL"
Else
	_Debug$ + #CR$ + "Inégal"
EndIf

_Debug$ + #CR$ + ""
_Debug$ + #CR$ + "autre test"
_Debug$ + #CR$ + ""

c = 165.356
d = 165.355

_Debug$ + #CR$ + StrF(c)
_Debug$ + #CR$ + StrF(d)

If IS_EGAL(c, d, 0.001)
	_Debug$ + #CR$ + "EGAL à 0,001 près"
Else
	_Debug$ + #CR$ + "Inégal"
EndIf

If IS_EGAL1(c, d, 0.001)
	_Debug$ + #CR$ + "EGAL à 0,001 près"
Else
	_Debug$ + #CR$ + "Inégal"
EndIf

If IS_EGAL_STRING(c, d, 3)
	_Debug$ + #CR$ + "EGAL à 3 decimales près"
Else
	_Debug$ + #CR$ + "Inégal"
EndIf


If IS_EGAL(c, d, 0.0001)
	_Debug$ + #CR$ + "EGAL à 0,0001 près"
Else
	_Debug$ + #CR$ + "Inégal"
EndIf

nb = 1000000000

t = ElapsedMilliseconds()
For i = 0 To nb
	If IS_EGAL(c, d, 0.0001)
		
	Else
		
	EndIf
Next
_Debug$ + #CR$ + "1 000 000 000 de tests : Macro : ABS()  " + Str(ElapsedMilliseconds()-t)


t = ElapsedMilliseconds()
For i = 0 To nb
	If IS_EGAL1(c, d, 0.0001)
		
	Else
		
	EndIf
Next
_Debug$ + #CR$ + "1 000 000 000 de tests : Macro : <= et >=  " + Str(ElapsedMilliseconds()-t)


t = ElapsedMilliseconds()
For i = 0 To nb
	If c = d
		
	Else
		
	EndIf
Next
_Debug$ + #CR$ + "1 000 000 000 de tests : référence  " + Str(ElapsedMilliseconds()-t)


t = ElapsedMilliseconds()
For i = 0 To 1000000
	If IS_EGAL_STRING(c, d, 3)
		
	Else
		
	EndIf
Next
_Debug$ + #CR$ + "    1 000 000 de tests : Macro : strf()  " + Str(ElapsedMilliseconds()-t)


MessageRequester("", _Debug$)
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Torp
Messages : 360
Inscription : lun. 22/nov./2004 13:05

Re: Petit problème de Float

Message par Torp »

Fred a écrit :C'est parce que c'est pas égal, tout simplement :)
Oui c'est un façon de voir les choses... Disons que "en informatique" cela n'est pas égal, mais pour le commun des mortels cela l'est :D

Merci pour votre aide.
Pour info, j'avais bien lu l'aide de PB... Mais je n'avais jamais rencontré le problème vicieux que cela pouvait poser... J'ai fait une Calculatrice (http://www.app-art.fr/phicalculator/index.html) dans le cadre de mon boulot que nous nous servons depuis 2 ans et hier, c'est un utilisateur qui m'a remonté un problème d'incohérences de résultats dans un cas bien précis de valeurs saisies, où le test d'égalité foire...

Par contre pourquoi le type double ne pose pas le même problème ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Petit problème de Float

Message par Backup »

Torp a écrit :Par contre pourquoi le type double ne pose pas le même problème ?
logiquement, je suppose que ton nombre "Rentre" dans un Double ..

mais si tu utilises des nombres qui ne rentre pas (qui depasse la capacité) d'un Double tu aura le meme soucis ..

( ça me rappel le Test Hebdogiciel ... ;) )
Torp
Messages : 360
Inscription : lun. 22/nov./2004 13:05

Re: Petit problème de Float

Message par Torp »

Ben en fait je viens de vérifier le type double pose les même problèmes mais pas au même moments... ce qui est logique.

Du coup comme l'a dit Graph100 les test d'égalité avec les nombres à virgules sont un peu comme la roulette russe.

Edit : Voilà ce qu'explique Microsoft (solution utilisée par Graph100 un peu plus haut) :

Code : Tout sélectionner

Pour tester de manière fiable l'égalité en virgule flottante (dans n'importe quel format en virgule flottante binaire, telles que IEEE ou au Format binaire Microsoft), vous devez soustraire deux nombres à virgule flottante qui sont comparés et vérifier si leur différence est inférieure à une valeur dans les limites de leur importance pour simple ou double précision.
Répondre