OVH Cloud OVH Cloud

BUG dans VBScript ??

8 réponses
Avatar
Pierre
Bonjour,

Voici un bout de VBScript qui en plus de me dérouter, pose de graves
problèmes à mon client qui effectue des calculs mathématiques importants :

<html>
<%
dim v, d
v=0.58
d=2
response.write "d = " & d & "<br>"
response.write "v = " & v & "<br>"
response.write "fix(v*10^d)*10^-d = " & fix(v*10^d)*10^-d & "<br>"
response.write "int(v*10^d)*10^-d = " & int(v*10^d)*10^-d & "<br>"
%>
</html>

La sortie de ce code est la suivante :

d = 2
v = 0,58
fix(v*10^d)*10^-d = 0,57
int(v*10^d)*10^-d = 0,57

Ce qui est assez fabuleux vous en conviendrez.

Que faire donc ???
Ces erreurs d'arrondis posent de graves problèmes comme je disais
précédemment, et sous VBscript il n'est pas semble-t-il possible de
travailler avec le type "decimal" au lieu du type "double" qui est flottant.

Pourquoi cela se produit-il ?
Comment eviter cela ?
Existe-t-il une mise à jour de la DLL ASP ?

Honnetement je suis très embarrasé par ce problème. Si même l'ordinateur ne
compte plus correctement, le monde est à refaire et tout mon application
aussi par la même occasion (400 pages asp + les classes et les contrôles)

HELP !!!!


Merci.

Pierre.

8 réponses

Avatar
Jean-Claude BELLAMY
Dans le message news: ,
Pierre s'est ainsi exprimé:

Bonjour,

Voici un bout de VBScript qui en plus de me dérouter, pose de graves
problèmes à mon client qui effectue des calculs mathématiques
importants :
<html>
<%
dim v, d
v=0.58
d=2
response.write "d = " & d & "<br>"
response.write "v = " & v & "<br>"
response.write "fix(v*10^d)*10^-d = " & fix(v*10^d)*10^-d & "<br>"
response.write "int(v*10^d)*10^-d = " & int(v*10^d)*10^-d & "<br>"
%>
</html>

La sortie de ce code est la suivante :

d = 2
v = 0,58
fix(v*10^d)*10^-d = 0,57
int(v*10^d)*10^-d = 0,57

Ce qui est assez fabuleux vous en conviendrez.


Ah bon ?
Je ne vois pas où est le problème !

"int" et "fix" sont 2 fonctions qui retournent la PARTIE ENTIÈRE d'un nombre
NB: la différence entre les 2 se situe uniquement au niveau des nombres
négatifs.
int(-14.23) = -15 (le nbre <0 immédiatement inférieur ou égal)
fix(-14.23) = -14 (le nbre <0 immédiatement supérieur ou égal)

Donc ici (nbres >0) , fix et int sont strictement analogues.


Quand tu calcules v*10^d ,j cela donne 58, mais en réalité, en interne,
c'est peut-être 57.999999999
Donc int retourne 57, ce qui est NORMAL.


Si tu veux un arrondi au plus juste, il faut utiliser la fonction "round"
http://www.bellamyjc.org/fr/vbsfunctions/vsfctround.html

Et là, çà marche ...
response.write "round(v*10^d)*10^-d = " & round(v*10^d)*10^-d & "<br>"
va afficher 0,58

--
May the Force be with You!
La Connaissance s'accroît quand on la partage
----------------------------------------------------------
Jean-Claude BELLAMY [MVP] - http://www.bellamyjc.org
*

Avatar
Pierre
C'est bon, ça j'avais compris que si fix ou int donne 0.57 c'est parce qu'en
interne il y a un 0.57999999 quelque part à cause des float.

Ma demande était de savoir s'il n'y avait pas un moyen en vbs de travailler
avec des "decimal" à la place des "double" et autres "single".



"Jean-Claude BELLAMY" a écrit dans le
message de news:
Dans le message news: ,
Pierre s'est ainsi exprimé:

Bonjour,

Voici un bout de VBScript qui en plus de me dérouter, pose de graves
problèmes à mon client qui effectue des calculs mathématiques
importants :
<html>
<%
dim v, d
v=0.58
d=2
response.write "d = " & d & "<br>"
response.write "v = " & v & "<br>"
response.write "fix(v*10^d)*10^-d = " & fix(v*10^d)*10^-d & "<br>"
response.write "int(v*10^d)*10^-d = " & int(v*10^d)*10^-d & "<br>"
%>
</html>

La sortie de ce code est la suivante :

d = 2
v = 0,58
fix(v*10^d)*10^-d = 0,57
int(v*10^d)*10^-d = 0,57

Ce qui est assez fabuleux vous en conviendrez.


Ah bon ?
Je ne vois pas où est le problème !

"int" et "fix" sont 2 fonctions qui retournent la PARTIE ENTIÈRE d'un
nombre
NB: la différence entre les 2 se situe uniquement au niveau des nombres
négatifs.
int(-14.23) = -15 (le nbre <0 immédiatement inférieur ou égal)
fix(-14.23) = -14 (le nbre <0 immédiatement supérieur ou égal)

Donc ici (nbres >0) , fix et int sont strictement analogues.


Quand tu calcules v*10^d ,j cela donne 58, mais en réalité, en interne,
c'est peut-être 57.999999999
Donc int retourne 57, ce qui est NORMAL.


Si tu veux un arrondi au plus juste, il faut utiliser la fonction "round"
http://www.bellamyjc.org/fr/vbsfunctions/vsfctround.html

Et là, çà marche ...
response.write "round(v*10^d)*10^-d = " & round(v*10^d)*10^-d & "<br>"
va afficher 0,58

--
May the Force be with You!
La Connaissance s'accroît quand on la partage
----------------------------------------------------------
Jean-Claude BELLAMY [MVP] - http://www.bellamyjc.org
*





Avatar
Jean
Bonjour,

ce problème avait été soulevé ici dans le fil suivant :
http://www.google.com/groups?hl=fr&lr=&thð579ec3cb4ea3ce&rnum=1

Amicalement,

Jean - JMST
Belgium

"Pierre" a écrit dans le message de news: %
C'est bon, ça j'avais compris que si fix ou int donne 0.57 c'est parce qu'en interne il y a un 0.57999999 quelque part à cause des
float.

Ma demande était de savoir s'il n'y avait pas un moyen en vbs de travailler avec des "decimal" à la place des "double" et autres
"single".



"Jean-Claude BELLAMY" a écrit dans le message de news:
Dans le message news: ,
Pierre s'est ainsi exprimé:

Bonjour,

Voici un bout de VBScript qui en plus de me dérouter, pose de graves
problèmes à mon client qui effectue des calculs mathématiques
importants :
<html>
<%
dim v, d
v=0.58
d=2
response.write "d = " & d & "<br>"
response.write "v = " & v & "<br>"
response.write "fix(v*10^d)*10^-d = " & fix(v*10^d)*10^-d & "<br>"
response.write "int(v*10^d)*10^-d = " & int(v*10^d)*10^-d & "<br>"
%>
</html>

La sortie de ce code est la suivante :

d = 2
v = 0,58
fix(v*10^d)*10^-d = 0,57
int(v*10^d)*10^-d = 0,57

Ce qui est assez fabuleux vous en conviendrez.


Ah bon ?
Je ne vois pas où est le problème !

"int" et "fix" sont 2 fonctions qui retournent la PARTIE ENTIÈRE d'un nombre
NB: la différence entre les 2 se situe uniquement au niveau des nombres négatifs.
int(-14.23) = -15 (le nbre <0 immédiatement inférieur ou égal)
fix(-14.23) = -14 (le nbre <0 immédiatement supérieur ou égal)

Donc ici (nbres >0) , fix et int sont strictement analogues.


Quand tu calcules v*10^d ,j cela donne 58, mais en réalité, en interne, c'est peut-être 57.999999999
Donc int retourne 57, ce qui est NORMAL.


Si tu veux un arrondi au plus juste, il faut utiliser la fonction "round"
http://www.bellamyjc.org/fr/vbsfunctions/vsfctround.html

Et là, çà marche ...
response.write "round(v*10^d)*10^-d = " & round(v*10^d)*10^-d & "<br>"
va afficher 0,58

--
May the Force be with You!
La Connaissance s'accroît quand on la partage
----------------------------------------------------------
Jean-Claude BELLAMY [MVP] - http://www.bellamyjc.org
*









Avatar
Do Re Mi chel La Si Do
Bonsoir !

A ma connaissance, VB-script ne supporte pas décimal. Microsoft a seulement
suivi l'IEEE 754, sur les flottants.

Pour info, Python a intégré un vrai module "decimal", avec la version 2.4

En restant avec VB-script, il faudra donc se rabattre sur les fonctions
d'arrondis, de tronquature, et de cast.




Pour d'autres lecteurs :

les flottants IEEE-754 utilisent une représentation basée sur les puissances
de 2 ; les librairies "decimal" sont sensées travailler sur des puissances
de 10. Mais ces librairies sont assez lentes.

A noter que, en Python, un decimal peut être créé uniquement à partir d'un
entier, d'un string, ou d'un autre decimal (par héritage), et que Python
utilise les tuples pour la représentation interne (ce qui est encore plus
lent, mais fournit une précision infinie).
J'ai essayé avec des nombres de 100 chiffres, avec 50 chiffres derrière la
virgule, et ça marche.

Peut-être qu'un jour, Microsoft se penchera sur le problème... En
attendant, il est toujours possible d'appeler des scripts Python depuis VBS.



Bonne soirée.
--
Michel Claveau
Avatar
Pierre
Merci Michel, enfin une réponse qui laisse un espoir ;-)

Je ne connais pas du tout Python, mais rien que pour ça suis intéressé.
Simplement pour débuter : comment appeler le script python depuis la page
ASP en vbs ?

Re-Merci.

Pierre

Pourrais-tu
"Do Re Mi chel La Si Do" a écrit dans le
message de news:
Bonsoir !

A ma connaissance, VB-script ne supporte pas décimal. Microsoft a
seulement
suivi l'IEEE 754, sur les flottants.

Pour info, Python a intégré un vrai module "decimal", avec la version 2.4

En restant avec VB-script, il faudra donc se rabattre sur les fonctions
d'arrondis, de tronquature, et de cast.




Pour d'autres lecteurs :

les flottants IEEE-754 utilisent une représentation basée sur les
puissances
de 2 ; les librairies "decimal" sont sensées travailler sur des puissances
de 10. Mais ces librairies sont assez lentes.

A noter que, en Python, un decimal peut être créé uniquement à partir
d'un
entier, d'un string, ou d'un autre decimal (par héritage), et que Python
utilise les tuples pour la représentation interne (ce qui est encore plus
lent, mais fournit une précision infinie).
J'ai essayé avec des nombres de 100 chiffres, avec 50 chiffres derrière la
virgule, et ça marche.

Peut-être qu'un jour, Microsoft se penchera sur le problème... En
attendant, il est toujours possible d'appeler des scripts Python depuis
VBS.



Bonne soirée.
--
Michel Claveau











Avatar
Pierre
Merci Jean.

Super piste.

Je recommande la lecture des articles suivant :

http://support.microsoft.com/default.aspx?scid=kb;en-us;196652
http://support.microsoft.com/default.aspx?scid=kb;en-us;36068

Pierre.


"Jean" <http:// a écrit dans le message de news:
eIHa2%
Bonjour,

ce problème avait été soulevé ici dans le fil suivant :
http://www.google.com/groups?hl=fr&lr=&thð579ec3cb4ea3ce&rnum=1

Amicalement,

Jean - JMST
Belgium

"Pierre" a écrit dans le message de news:
%
C'est bon, ça j'avais compris que si fix ou int donne 0.57 c'est parce
qu'en interne il y a un 0.57999999 quelque part à cause des float.

Ma demande était de savoir s'il n'y avait pas un moyen en vbs de
travailler avec des "decimal" à la place des "double" et autres "single".



"Jean-Claude BELLAMY" a écrit dans le
message de news:
Dans le message news: ,
Pierre s'est ainsi exprimé:

Bonjour,

Voici un bout de VBScript qui en plus de me dérouter, pose de graves
problèmes à mon client qui effectue des calculs mathématiques
importants :
<html>
<%
dim v, d
v=0.58
d=2
response.write "d = " & d & "<br>"
response.write "v = " & v & "<br>"
response.write "fix(v*10^d)*10^-d = " & fix(v*10^d)*10^-d & "<br>"
response.write "int(v*10^d)*10^-d = " & int(v*10^d)*10^-d & "<br>"
%>
</html>

La sortie de ce code est la suivante :

d = 2
v = 0,58
fix(v*10^d)*10^-d = 0,57
int(v*10^d)*10^-d = 0,57

Ce qui est assez fabuleux vous en conviendrez.


Ah bon ?
Je ne vois pas où est le problème !

"int" et "fix" sont 2 fonctions qui retournent la PARTIE ENTIÈRE d'un
nombre
NB: la différence entre les 2 se situe uniquement au niveau des nombres
négatifs.
int(-14.23) = -15 (le nbre <0 immédiatement inférieur ou égal)
fix(-14.23) = -14 (le nbre <0 immédiatement supérieur ou égal)

Donc ici (nbres >0) , fix et int sont strictement analogues.


Quand tu calcules v*10^d ,j cela donne 58, mais en réalité, en interne,
c'est peut-être 57.999999999
Donc int retourne 57, ce qui est NORMAL.


Si tu veux un arrondi au plus juste, il faut utiliser la fonction
"round"
http://www.bellamyjc.org/fr/vbsfunctions/vsfctround.html

Et là, çà marche ...
response.write "round(v*10^d)*10^-d = " & round(v*10^d)*10^-d &
"<br>"
va afficher 0,58

--
May the Force be with You!
La Connaissance s'accroît quand on la partage
----------------------------------------------------------
Jean-Claude BELLAMY [MVP] - http://www.bellamyjc.org
*













Avatar
Do Re Mi chel La Si Do
Bonjour !

Quelques renseignements, en vrac (mais incomplets) :

- Python étant un langage dynamique et autoiconique, il est facile de lui
faire exécuter du code à la volée
- L'extension PyWin (anciennement Win32all) permet de réaliser un serveur
COM, capable d'exécuter du code qui lui sera transmis par une chaîne de
caractères. Pour faire cela, une trentaine de lignes suffit.
- Comme il existe un modPython, pour intégrer Python à Apache, il existe des
modules pour intégrer le langage à ASP. Mais je n'ai jamais fait ça,
préférant écrire mes propres serveurs web (en Python, bien sûr).
- Inversement, il est facile, sous Python, d'appeler un script VBS ou JS, en
instanciant "ScriptControl"

Python n'est pas parfait. S'il est relativement facile à apprendre, avec un
code très clair, et de gigantesques librairies, il souffre aussi de
certaines caractéristiques assez subtiles, ou pas évidentes à assimiler (par
exemple le concept de métaclasses, permettant d'intervenir sur les
superclasses, avant d'avant hériter). Je regrette aussi qu'il n'y ait de
programmation par prototypage.
Mais je te rassure : la P.O.O. n'est pas obligatoire, en Python.

Autre défaut, il n'y a pas de véritable implémentation dans .NET (mais...)


Bref, quelques liens, pour aller plus loin :

http://www.python.org/ (rappel : decimal est une nouveauté de la version
2.4)
http://www.python.org/download/ (pour télécharger)
http://www.python.org/doc/2.4/ (de la doc)
http://www.python.org/sigs/ (les SIGs)
http://sourceforge.net/projects/pywin32/ (le module pour windows)
http://starship.python.net/crew/theller/ctypes/ (accès aux types C depuis
Python ; pour utiliser directement les API windows et autres DLL)
http://www.vex.net/parnassus/ (beaucoup de liens)
http://www.python.org/pypi (des modules/librairies)
http://www.uselesspython.com/tutorials.html (encore des modules)
http://olberger.club.fr/python/doc/tut/index.html (ancien, mais en
français)
http://www.idealx.org/doc/instant_fr.fr.html (une mini-page d'introduction)

Sur Usenet :
fr.comp.lang.python
comp.lang.python (j'ai une archive de 125 000 messages)


Enfin, il existe plusieurs livres en français. J'ai lu notamment :
"Introduction à Python" (chez O'Reilly) assez ancien, mais qui explique bien
les principes de base de Python
"Python en concentré" (O'Reilly aussi) plutôt dense, recouvre beaucoup
d'aspects, mais les explications sont succinctes, malgré 600 pages bien
fournies (il faudrait 10 000 pages...)

Si ça ne suffit, pas, je dois avoir une centaine de liens sur Python.



@-salutations
--
Michel Claveau
Avatar
Daniel92
Hello Michel!

: - Python étant un langage dynamique et autoiconique, il est facile de lui
: faire exécuter du code à la volée

Là je suis largué qu'est-ce que c'est ? :

- un langage dynamique et autoiconique

- exécuter du code à la volée

En 2 mots le reste j'irai le chercher en cas de besoin.

Merci,
Daniel.
====