PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 25 → BUG Arrondi
BUG Arrondi
Débuté par Philippe SB, 20 déc. 2019 15:26 - 16 réponses
Membre enregistré
1 947 messages
Posté le 20 décembre 2019 - 15:26
Attention la fonction Arrondi est fausse dans certains cas.

Faites les test suivant, vous serez surpris.
Trace(0.7*6.85,Arrondi(0.7*6.85,2),Arrondi(4.795,2))


--
Cordialement,

Philippe SAINT-BERTIN
Posté le 20 décembre 2019 - 16:15
Ce n'est bug mais une fonctionnalité. :)

C'est dû au fait que l'opération est stocké dans un réel or, les valeurs stocké dans un réel ne sont jamais exact.
(cf http://gabriel.risterucci.perso.luminy.univ-amu.fr/HUGo/float.htm que je n'ai pas lu mais dont le titre me semble expliquer ce que je souhaite)

pour résoudre le problème, on utilise un monétaire ou un numérique
LOCAL
mValeur est un monetaire
nuValeur est un numerique (6, 3)

mValeur = 0.7*6.85
nuValeur = 0.7*6.85
Trace(0.7*6.85,Arrondi(0.7*6.85,2),Arrondi(4.795,2), "###", mValeur, arrondi(mValeur, 2), nuValeur, arrondi(nuValeur, 2))
Membre enregistré
1 947 messages
Posté le 29 décembre 2019 - 15:38
si si c'est un énorme bug.

Je sais bien que l'opération renvoie un réel, mais sachant que les réels n'ont justement aucune valeur exacte, l'opération devrait être effectuée par défaut sur un numérique de manière à ne pas se retrouver avec ce type de problème.

On est en WLangage et non en C ou C++. On paye pour s'affranchir de ce type de problème.

--
Cordialement,

Philippe SAINT-BERTIN
Posté le 30 décembre 2019 - 08:21
Bonjour,

> si si c'est un énorme bug.

Non, non. Il s'agit d'un comportement normal et je ne vois pas comment tu peux affirmer qu'il s'agisse d'autre chose, surtout avec la piètre démonstration que tu nous as présenté. Il y a suffisamment de vrais bugs dans l'outil pour ne pas jouer sur les mots avec ce qui fonctionne parfaitement.

Je sais bien que l'opération renvoie un réel, mais sachant que les réels n'ont justement aucune valeur exacte, l'opération devrait être effectuée par défaut sur un numérique de manière à ne pas se retrouver avec ce type de problème.
On est en WLangage et non en C ou C++. On paye pour s'affranchir de ce type de problème.


A ce jour, c'est très certainement la démonstration la plus bidon qu'il m'ait été donnée de lire!
C'est un peu comme si tu demandais à ce que l'enseignement privé s'affranchisse de l'intelligence des tes gamins et en fasse automatiquement des génies, au seul prétexte que tu payes le prix fort.

Un peu de sérieux, la fonction arrondi renvoie ce que tu demandes (soit un réel, soit un monétaire), encore faut-il le demander et déclarer correctement tes variables…

Et un peu de lecture de la documentation, t'aurait évité d'écrire n'importe quoi :

 : Réel ou monétaire
Valeur numérique à arrondir. Le type monétaire est conseillé pour obtenir des résultats fiables.


et

Attention : Les arrondis avec le type "Réel" ne sont pas précis. En effet, les opérations avec le type "réel" ne sont pas précises du fait de la représentation informatique des réels. Pour obtenir un arrondi exact, il est conseillé d'utiliser le type Monétaire ou Numérique qui utilise une représentation mémoire exacte. Pour plus de détails, consultez le type réél.
Membre enregistré
1 947 messages
Posté le 30 décembre 2019 - 17:10
@Mouhahahahahaha!
Je te remercie mais je ne sais pas pour qui tu te prends pour juger les gens de la sorte. Je connais tous les problèmes que peuvent entraîner les réels et c'est la raison pour laquelle je n'en n'utilise jamais.

Ton exemple sur le système scolaire est complètement hors sujet et je te prierai de bien vouloir laisser mes enfants en dehors de tout ça. Te comporter comme ça prouve que l'idiot ici c'est toi...

Tout d'abord nous sommes sur un langage de 5ème génération et je trouverai normal qu'à ce niveau les numériques soient utilisés par défaut et non les réels pour effectuer ce type d'opération. Si tu souhaites utiliser des réels alors tu déclares une variable de ce type spécifiquement. Nous payons pour nous affranchir de ce type de problème.

Lorsque tu ne déclares pas de variable, les calculs devraient selon moi se faire comme sur une variable de type numérique de façon à avoir toujours valeur exacte.

Comment peux-tu m'expliquer que windev soit capable d'afficher un résultat correct en faisant 0.7*6.85 soit 4.795 ? Où est le reste de l'imprécision ?

Lorsque tu fais Arrondi(4.795,2), 4.795 est un flottant ou est considéré comme un numérique ? S'il n'y a pas le reste de l'imprécision pourquoi n'a-t-on pas le même arrondi ?

Pourquoi a-t-on le droit de faire ce genre de calcul si PC Soft sait pertinemment que le résultat sera imprécis ???

Et je te remercie également mais je n'ai pas besoin de ta lecture, je sais déjà de quoi je parle.

--
Cordialement,

Philippe SAINT-BERTIN
Membre enregistré
1 176 messages
Posté le 30 décembre 2019 - 17:36
Bonjour
Philippe SB a écrit :
Pourquoi a-t-on le droit de faire ce genre de calcul si PC Soft sait pertinemment que le résultat sera imprécis ???

Pour la même raison qu'on a le droit d'écrire :
LeTaureau est entier
LePereNoel est monétaire

LePereNoel=25.12
LeTaureau=LePereNoel


A partir d'un certain moment, on sait quand même ce que l'on fait

--
Il y a peut être plus simple, mais, ça tourne
Membre enregistré
1 947 messages
Posté le 30 décembre 2019 - 18:06
Oui je sais ce que je fais. Cependant à partir du moment où l'on ne déclare pas de variable le résultat n'a plus de sens. Il n'est nullement spécifié que le résultat est forcément un réel, il pourrait être un numérique avec la précision attendue.

Si je mets
toto est reel = 0.7*6.85


Je conçois que le résultat soit un réel et que la précision ne soit pas exceptionnelle, Or ce n'est pas le cas... et je n'ai jamais stocké le résultat d'un monétaire dans un entier tout en me posant la question de savoir pourquoi je n'ai pas les décimales. Vous vous acharnez à me donner des exemples qui n'ont rien à voir.

J'essaye de vous expliquer une chose qui devrait être évidente en wlangage. Je ne parle pas de langages type C/C++.

Je vous souhaite juste de tomber sur le cas un jour et de chercher pendant des heures pourquoi vos totaux sont faux. Ce jour vous vous direz certainement que si le calcul était traité comme un numérique avec la précision attendue ça aurait été plu simple.

Rien ne vaut sa propre expérience.

--
Cordialement,

Philippe SAINT-BERTIN
Posté le 30 décembre 2019 - 18:44
Philippe SB a écrit :

>Te comporter comme ça prouve que l'idiot ici c'est toi...

Bah, ça m'empêche pas de lire la documentation avant d'écrire mes âneries :p

Tout d'abord nous sommes sur un langage de 5ème génération et je trouverai normal qu'à ce niveau les numériques soient utilisés par défaut et non les réels pour effectuer ce type d'opération. Si tu souhaites utiliser des réels alors tu déclares une variable de ce type spécifiquement. Nous payons pour nous affranchir de ce type de problème.


Il insiste le bougre!

Si tu souhaites utiliser des numériques alors tu déclares une variable de ce type spécifiquement! Tu vois l'idée?
Tu viens pas nous affirmer qu'il s'agit d'un énorme bug.

Que tu "trouverai normal que les numériques soient utilisés par défaut", c'est ton envie et un autre sujet. Cela ne transforme pas pour autant ta "découverte" en "un énorme bug" du Wlangage. Cela confirme simplement que tu n'as pas lu la doc.

> Lorsque tu ne déclares pas de variable, les calculs devraient selon moi se faire comme sur une variable de type numérique de façon à avoir toujours valeur exacte.

Encore une fois, c'est "selon toi" et par feignantise de déclaration de variable.

Comment peux-tu m'expliquer que windev soit capable d'afficher un résultat correct en faisant 0.7*6.85 soit 4.795 ? Où est le reste de l'imprécision ?
Lorsque tu fais Arrondi(4.795,2), 4.795 est un flottant ou est considéré comme un numérique ? S'il n'y a pas le reste de l'imprécision pourquoi n'a-t-on pas le même arrondi ?
Pourquoi a-t-on le droit de faire ce genre de calcul si PC Soft sait pertinemment que le résultat sera imprécis ???


Je me lance : Parce que cela a été prévu comme ça et qu'à un moment, faut savoir lire le manuel et s'adapter?

> Et je te remercie également mais je n'ai pas besoin de ta lecture, je sais déjà de quoi je parle.

Visiblement non.
Posté le 30 décembre 2019 - 18:59
Philippe SB a écrit :

> Oui je sais ce que je fais. Cependant à partir du moment où l'on ne déclare pas de variable le résultat n'a plus de sens. Il n'est nullement spécifié que le résultat est forcément un réel, il pourrait être un numérique avec la précision attendue.

D'où l'intérêt de ne pas être trop feignant et de prendre le soin de déclarer ses variables.

Je conçois que le résultat soit un réel et que la précision ne soit pas exceptionnelle, Or ce n'est pas le cas... et je n'ai jamais stocké le résultat d'un monétaire dans un entier tout en me posant la question de savoir pourquoi je n'ai pas les décimales. Vous vous acharnez à me donner des exemples qui n'ont rien à voir.


Tu t'acharnes à nous expliquer que tu ne déclares pas tes variables et tu t'obstines à vouloir nous faire adhérer à cette idée farfelue.

> Je vous souhaite juste de tomber sur le cas un jour et de chercher pendant des heures pourquoi vos totaux sont faux. Ce jour vous vous direz certainement que si le calcul était traité comme un numérique avec la précision attendue ça aurait été plu simple.

Deux heures à chercher pourquoi ses totaux sont faux, alors qu'une parfaite déclaration de variables aurait pris 10 secondes. La loose.


Rien ne vaut sa propre expérience.


Comme tu dis...
Membre enregistré
1 947 messages
Posté le 31 décembre 2019 - 10:07
Au temps pour moi je m'incline devant le maître du développement chez qui tout est parfait.

Tu ne dois pas faire beaucoup de TMA mon pauvre petit...

--
Cordialement,

Philippe SAINT-BERTIN
Membre enregistré
3 messages
Posté le 01 janvier 2020 - 17:25
Bonjour,
Pour éviter ce genre de problème, je précise simplement le type d'arrondi.
Trace(0.7*6.85,Arrondi(0.7*6.85,2),Arrondi(4.795,2))
Trace(0.7*6.85,ArrondiSupérieur(0.7*6.85,2),ArrondiSupérieur(4.795,2))
Trace(0.7*6.85,ArrondiInférieur(0.7*6.85,2),ArrondiInférieur(4.795,2))

Cordialement

Jean-Pierre
Posté le 02 janvier 2020 - 15:54
Philippe SB a écrit :
Je vous souhaite juste de tomber sur le cas un jour et de chercher pendant des heures pourquoi vos totaux sont faux. Ce jour vous vous direz certainement que si le calcul était traité comme un numérique avec la précision attendue ça aurait été plu simple.

Rien ne vaut sa propre expérience.


Je pense que la plupart d'entre nous avons subi les désagréments de ce type.
J'ai même vu un projet où les P.U. et montants était stocks sous forme de réels (oui, il y a eu des cris et des pleurs).

> J'essaye de vous expliquer une chose qui devrait être évidente en wlangage. Je ne parle pas de langages type C/C++.

Je pense que le fait que Windev utilise le fonctionnement "normal" des valeurs numériques (réel, entier, ...) est une bonne chose, j'imagine qu'il est plus rapide plus rapide d'utiliser un réel qu'un monétaire pour les opérations.

Toutefois, je trouve l'idée intéressante.
Je viens de découvrir que si on préfixe une valeur par 0n, cela va utiliser un type numérique (0m pour monetaire, 0r pour un réel) donc ceci renvoi le résutlat souhaité :
Trace(0n0.7*0n6.85, Arrondi(0n0.7*0n6.85,2),Arrondi(0n4.795,2))


Une évolution, où dans la description du projet on indiquerait qu'une valeur numérique saisie "en dure dans le code" soit considérée comme un "0n, 0m ou 0r".
Il ne faut pas oublier que les monetaires sont limité à 23 chiffres significatif et les numérique à 38 chiffres significatif. il faudrait donc généré une exception en cas de dépassement (ou si possible une erreur de compilation).


Pour info, au début je pensais vous proposer d'essayer de surcharger la fonction "arrondi". J'ai essayé par moi-même et là, je me suis aprerçu que le problème n'est pas la fonction "arrondi" (car l'arrondi de 4.79499999999999 sur 2 décimale est bien 4.79) mais la mulitplication.
Membre enregistré
264 messages
Posté le 03 janvier 2020 - 09:18
> Attention la fonction Arrondi est fausse dans certains cas.

Non elle n'est pas fausse, elle agît comme elle devrait...

Faut typer ses variables... y'a rien de mieux que l'exactitude et la précision. Il vaut mieux prévenir que guérir... Si vous ne précisiez pas la taille de vos pneus à votre garagiste, il ne faudra pas le critiquer quand il aura commandé des pneus standards, c'est à vous d'écrire proprement le code et ne pas passer par des raccourcis de codes houleux...

J'ai rarement vu quelqu'un être aussi ridicule aussi bien dans ses dires, qu'exemples ou arguments, et qui en plus insiste dans son erreur.

Si vous n'êtes pas content du produit et de la manière dont il fonctionne, c'est à dire pas par magie, changer de logiciel et arretez de nous faire perdre du temps avec une chose que l'on a tous expérimenté. L'arrondi c'est genre le truc basique de chez basique, donc déjà là on se pose des questions sur votre niveau, si vous coincez juste sur des "arrondi", j'ose pas imaginer le jour ou vous aller devoir jouer avec des dlls... Alors venir tenir des beaux discours sur le C / C++ ca me fait doucement rigoler...

En tout cas vous nous avez clairement montré ce qu'est le syndrôme dunning kruger et la différence entre quelqu'un qui se croit développeur et un VRAI développeur, suffit d'aller sur votre site internet pour comprendre de quel côté vous êtes.

Tu ne dois pas faire beaucoup de TMA mon pauvre petit...

Quand un logiciel est bien codé et robuste pas besoin de "Maintenance"... donc non effectivement ce monsieur qui vous explique que vous avez tort, et il a raison ne doit pas faire bcp de TMA, il semble maitriser le développement et son logiciel lui ;)
Message modifié, 03 janvier 2020 - 09:19
Membre enregistré
1 947 messages
Posté le 03 janvier 2020 - 09:31
@Poncherello: C'est bien ce que je dis toi non plus tu ne dois pas faire beaucoup de TMA. Tu penses que tous les développements ne sont faits que par moi ?

Ne change jamais de boîte tu pourrais te rendre compte que dans le monde du développement rien n'est parfait. Je maîtrise parfaitement mes logiciels mais j'ai aussi la maintenance de logiciels qui ont été fait par d'autres tiers. A priori ça te dépasse. Je te rassure j'ai suffisamment d'années de développement pour savoir ce que je fais et ce que je dis.

D'autres part, si tu fais la même opération sur un sgbd type sql server ou postgresql, tu constateras que l'arrondi donnera bien 4.8 et non 4.79. Qui a raison ? Vous les maîtres incontestés du développement qui êtes capables de n'avoir jamais de bug ou d'erreurs au sein de vos logiciels... J'applaudis des 2 mains et des 2 pieds. Reste bien dans ton petit monde illusoire et bon courage...

--
Cordialement,

Philippe SAINT-BERTIN
Membre enregistré
1 947 messages
Posté le 03 janvier 2020 - 09:59
@Poncherello: Juste pour info voici la définition de TMA, tu auras appris au moins une chose aujourd'hui ;) (https://fr.wikipedia.org/wiki/Tierce_maintenance_applicative)

--
Cordialement,

Philippe SAINT-BERTIN
Membre enregistré
27 messages
Posté le 14 février 2020 - 10:20
@Mouhahahahahaha!

tu as beaucoup parlé de lire la doc, mais tu as échoué à nous montrer l'endroit qui dit que les nombres non typés et leurs opérations arithmétiques étaient par défaut stockés en type "réel".

@Poncherello

la requête de Philippe SB est légitime et Dunning-Kruger ne s'applique pas ici

@Erwan

merci, ta contribution est utile et en sujet.
Membre enregistré
54 messages
Posté le 14 février 2020 - 12:03
@Alexis :

La déclaration "en direct" dans le code des valeurs utilisent l'inférence de type: https://doc.pcsoft.fr/fr-FR/?3087003&name=inference_type

La doc n'est pas précise mais il y a un exemple qui démontre qu'un chiffre déclaré en dur est en réel s'il contient des décimales :
soit Montant = 1500.69 // type réel


Un peu de code permet de le vérifier très rapidement
dbgVérifieEgalité(TypeVar(0.25),wlRéel) // OK
dbgVérifieEgalité(TypeVar(0.25),wlMonétaire) // Erreur
dbgVérifieEgalité(TypeVar(0.25),wlNumérique) // Erreur


Au final rien de très surprenant, le WLangage, quand on ne lui indique pas un besoin extrême de précision, utilise le type de variable le plus rapide pour les calculs et optimisations.

On pourra en vouloir à la documentation de ne pas être plus précise, mais étant donné que le comportement est le même que dans les autres langages, ça serait un peu gros d'en vouloir au langage ou au logiciel.