[R] Problème avec la fonction IsFloat

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
Sachadee
Niveau 2
Niveau 2
Messages : 23
Enregistré le : dim. 29 sept. 2013 03:50
Status : Hors ligne

[R] Problème avec la fonction IsFloat

#1

Message par Sachadee »

Bonjour à tous.

J'ai un petit problèmes avec la fonction IsFloat :

On est d'accord que 1.10 * 700 = 770
770 n'est pas une valeur en virgule flottante.

Pourtant si je fais :

Code : Tout sélectionner

Local $Totalproduit = 1.10 * 700
MsgBox("",$Totalproduit,IsFloat($Totalproduit))
ça me retourne 1

Si quelqu'un a une idée....
Modifié en dernier par Sachadee le jeu. 10 juil. 2014 19:22, modifié 1 fois.
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#2

Message par jchd »

AutoIt effectue une multiplication de double dès lors qu'un des opérandes est double.
Aussi, le résultat d'une division (même 1/1) est aussi un double, éventuellement une forme indéterminée ou un infini.

Code : Tout sélectionner

ConsoleWrite(0/0 & " -> " & VarGetType(0/0) & ", Float? -> " & IsFloat(0/0) & ", Int? -> " & IsInt(0/0) & @LF)
ConsoleWrite(1/0 & " -> " & VarGetType(1/0) & ", Float? -> " & IsFloat(1/0) & ", Int? -> " & IsInt(1/0) & @LF)
ConsoleWrite(-1/0 & " -> " & VarGetType(-1/0) & ", Float? -> " & IsFloat(-1/0) & ", Int? -> " & IsInt(-1/0) & @LF)
ConsoleWrite(1/1 & " -> " & VarGetType(1/1) & ", Float? -> " & IsFloat(1/1) & ", Int? -> " & IsInt(1/1) & @LF)
ConsoleWrite(1.0*3 & " -> " & VarGetType(1.0*3) & ", Float? -> " & IsFloat(1.0*3) & ", Int? -> " & IsInt(1.0*3) & @LF) 
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
Sachadee
Niveau 2
Niveau 2
Messages : 23
Enregistré le : dim. 29 sept. 2013 03:50
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#3

Message par Sachadee »

Merci pour ta réponse.

Mais comment faire pour réinitialiser cette valeur comme "Integer" car même si je fait
un :

Code : Tout sélectionner

Local $Totalproduit = 1.10 * 700
$Test=$TotalProduit*1
MsgBox("",$Test,IsFloat($Test))
$Test hérite apparemment des proprietés de $TotalProduit.

C'est vraiment étrange comme comportement.
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#4

Message par jchd »

Tu peux utiliser Int() mais à vrai dire il est rare que cela importe. Pour quelle raison tiens-tu à ce que le produit soit de type Integer ?

Soit dit au passage : IsFloat(1.10 * 700) renvoie 0. <<-- EDIT: pas vrai du tout, j'avais bu !

Je précise que je m'appuie sur la dernière version officielle, ce qui date de 3 ans m'importe peu.
Modifié en dernier par jchd le jeu. 10 juil. 2014 19:06, modifié 1 fois.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#5

Message par mikell »

Après avoir lu l'avant-dernière réponse de jc tu devrais avoir intégré le fait qu'il y a des mystères qu'il vaut mieux ne pas chercher à comprendre :mrgreen:
Cela dit c'est quand même étonnant que ce souci existe encore
http://www.autoitscript.com/trac/autoit/ticket/1854

Donc a priori

Code : Tout sélectionner

Local $Totalproduit = 1.1*100 

MsgBox(0, $Totalproduit, IsFloat($Totalproduit))
MsgBox(0, $Totalproduit, StringIsFloat($Totalproduit))
:roll:

Edit
IsFloat(1.10 * 700) renvoie bien 1 chez moi (3.3.12.0, dernière release)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#6

Message par jchd »

Oops, pardon. J'ai occulté le fait que 1.10 ne peut être représenté exactement en double.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#7

Message par mikell »

jc ça mériterait pas un ticket staffaire ?
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Sachadee
Niveau 2
Niveau 2
Messages : 23
Enregistré le : dim. 29 sept. 2013 03:50
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#8

Message par Sachadee »

Effectivement je viens de tester sur la dernière version officiel et ça retourne bien 1. Apparement ce bug est persistent :D

En fait JC mon problème était le suivant. C'est pour un sytème de transfert XML (web service) avec le Fisc Brésilien. Les valeurs doivent avoir un format bien précis (nb de décimale).

Donc je calcule le prix total pour un produit. Si c'est une valeur à virgule flottante je rajoute [00] et si non je rajoute [.00].

Code : Tout sélectionner

If IsFloat($Totalproduit) Then
     $TotalProduit = $Totalproduit & "00"
  Else
     $TotalProduit = $Totalproduit & ".00"
     EndIf
 
et ensuite je recupère la valeur avec juste les 2 dernières décimales.

Code : Tout sélectionner

 $Totalproduit = StringRegExp($Totalproduit, "(\d+[.,]\d{2})",1)
Voilà.

Apparement en remplaçant, comme proposé par Mikell que je remercie grandement, le IsFloat par un StringIsFloat ça fonctionne.


Merci à vous.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#9

Message par mikell »

Ah mais là le problème est différent, il te faut utiliser StringFormat

Code : Tout sélectionner

Local $a = 25
Local $b = 2.5
Local $c = 2.559

MsgBox(0,"",  StringFormat("%.02f", $a) & @crlf & StringFormat("%.02f", $b) & @crlf & StringFormat("%.02f", $c))
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
Sachadee
Niveau 2
Niveau 2
Messages : 23
Enregistré le : dim. 29 sept. 2013 03:50
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#10

Message par Sachadee »

Excellent !

C'est effectivement vraiment plus simple.

Merci.

:wink:
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [..] Problème avec la fonction IsFloat

#11

Message par jchd »

Voir ceci ou celà où ma remarque est en avant-dernier post.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#12

Message par mikell »

Sans doute, mais même si le comportement d'Autoit est peut-être techniquement justifié sur le coup (I don't understand its internal behaviour), reste quand même que cette fonction IsFloat() retourne un résultat faux, alors que StringIsFloat() en retourne un exact
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#13

Message par jchd »

Faux vs exact : tout est relatif. En réalité ces fonctions sont correctes en ce sens qu'elles satisfont leurs spécifications, celles données dans l'aide.

Code : Tout sélectionner

ConsoleWrite(1.10*700 & " -> " & VarGetType(1.10*700) & ", Float? -> " & IsFloat(1.10*700) & ", Int? -> " & IsInt(1.10*700) & ", Hex = " & Hex(1.10*700) & @LF)

produit :
770 -> Double, Float? -> 1, Int? -> 0, Hex = 4088100000000001 
Donc IsFloat() est correcte (le double possède effectivement une partie décimale).
StringIsFloat() est aussi correcte en ce qu'elle ne détecte pas de partie décimale, car elle disparaît à cause de l'arrondi implicite effectué par la conversion double -> chaîne.

Pour s'en assurer :

Code : Tout sélectionner

ConsoleWrite(StringFormat("%3.16f", 1.10*700) & @LF)

produit :
770.0000000000001100
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#14

Message par jchd »

mikell,

Pourquoi remontes-tu ce ticket #1854 ? Le code ne sort rien d'étrange pour moi ?
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#15

Message par mikell »

Non non rien à dire avec StringIsFloat, j'ai juste évoqué ce ticket à cause de son titre "StringIsFloat returns 1 on non float numbers" en suggérant que la fonction IsFloat mériterait peut-être un ticket avec un titre équivalent
Je comprends bien que les mécanismes de calcul internes sont particuliers et que ceci peut expliquer cela, mais l'aide disant pour IsFloat : "The function will return 0 if the value is a float with no fractional component (e.g. 1.000)", pour moi qui ne suis pas grand technicien (comme au moins 90% des utilisateurs d'Autoit j'imagine) je traduis bêtement par : cette fonction va me permettre de détecter si un nombre comporte des décimaux ou pas, et dans ce sens tout ça prête vachement à confusion ... dans la mesure où StringIsFloat répond exactement à ce qu'on peut en attendre, on serait en droit de s'interroger sur le fait que IsFloat retourne un résultat différent
Mais si ce fonctionnement est effectivement normal alors il serait plus qu'opportun de mettre un warning dans l'aide (genre "ne pas confondre...")
Le titre du présent topic est une parfaite illustration de cette confusion
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#16

Message par jchd »

Malheureusement et tant qu'on persistera à utiliser des flottants binaires, ce genre de souci continuera d'apparaître régulièrement. Mais dans ce cas particulier, on ne doit pas assimiler la partie fractionnaire d'un flottant (sous forme double) avec la présence de décimales lors de sa conversion implicite en chaîne.

Il est logique d'afficher (donc sous forme chaîne) 1.10 * 700 et qu'on voie 770 et il est tout aussi cohérent qu'un test du résultat avec IsFloat (donc un test portant sur un type double) nous informe que ce n'est pas un entier exact, puisque 1.1 ne peut pas être représenté exactement par un double.

StringIsFloat demande un paramètre chaîne, ce qui implique une conversion interne de double vers chaîne, conversion qui pratique un arrondi salvateur dans la plupart des situations. On aurait bien plus de hurlements (à juste titre AMHA) si ConsoleWrite(1.10*700) affichait 770.000000000000110

Une note dans l'aide ne servirait guère : l'aide sur le détail des types et autre "Language Reference" n'est que rarement consultée. 99% des gens postent leur désaroi lorsqu'ils rencontrent un tel problème, ayant implicitement espéré que les opérations flottantes (binaires) puissent refléter exactement les opérations décimales auxquelles nous sommes habitués depuis notre plus tendre enfance.

ConsoleWrite(StringFormat("%3.16f", 1.1*1.3) & @LF) --> 1.4300000000000002
D'où diable sort donc ce 2 ?

ConsoleWrite(StringFormat("%3.16f", 1.4) & @LF) --> 1.3999999999999999
J'avais pourtant bien dit 1.4, non ?
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#17

Message par mikell »

Moui... et pour vérifier qu'un nombre (pas une string !) est un entier on utilise IsInt (et pas StringIsInt) alors que pour vérifier s'il a des décimales c'est StringIsFloat (et pas IsFloat)
Tout ça est limpide mais pas vraiment clair (et réciproquement)
Comment tu veux que le béotien que je suis, il s'y retrouve ? :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jchd
AutoIt MVPs (MVP)
AutoIt MVPs (MVP)
Messages : 2284
Enregistré le : lun. 30 mars 2009 22:57
Localisation : Sud-Ouest de la France (43.622788,-1.260864)
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#18

Message par jchd »

Tout dépend du sens que tu donnes à "avoir des décimales".
Si tu penses aux éventuelles décimales qui apparaîtraient même après conversion en chaîne, c'est StringIsFloat.
Si tu t'intéresses aux décimales de haut rang (genre 1e-14) qu'on néglige la plupart du temps, c'est IsFloat, IsInt ou Frac.
La cryptographie d'aujourd'hui c'est le taquin plus l'électricité.
Avatar du membre
Sachadee
Niveau 2
Niveau 2
Messages : 23
Enregistré le : dim. 29 sept. 2013 03:50
Status : Hors ligne

Re: [R] Problème avec la fonction IsFloat

#19

Message par Sachadee »

Tout dépend du sens que tu donnes à "avoir des décimales".
Si tu penses aux éventuelles décimales qui apparaîtraient même après conversion en chaîne, c'est StringIsFloat.
Si tu t'intéresses aux décimales de haut rang (genre 1e-14) qu'on néglige la plupart du temps, c'est IsFloat, IsInt ou Frac.
Là ça devient bien plus clair.

Merci.
Répondre