Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

soustraction en VB

8 réponses
Avatar
Bonjour,

Je viens de remarquer un prbl dans mon programme, en faisant :

msgbox 8.12 - 8 j'ai 0.11999999999

Pour moi 8.12 - 8 = 0.12, visiblement c'est pas le cas de VB

Si quelqu'un a des infos sur le sujet ou une methode plus juste pour
calculer, je vous remercie d'avance.

Cordialement.

Damien

8 réponses

Avatar
Vincent Guichard
util a écrit :
Bonjour,

Je viens de remarquer un prbl dans mon programme, en faisant :

msgbox 8.12 - 8 j'ai 0.11999999999

Pour moi 8.12 - 8 = 0.12, visiblement c'est pas le cas de VB

Si quelqu'un a des infos sur le sujet ou une methode plus juste pour
calculer, je vous remercie d'avance.

Cordialement.

Damien





Bienvenue dans le monde des calculs numérique!

8.12 est par défaut converti en double. Le type double a une
représentation binaire en mémoire définie (dans une norme IEEE, mais je
sais plus son numéro). Cette représentation ne peux bien sur pas
exprimer _toutes_ les valeurs possibles, puisqu'il existe une infinité
de valeurs et l'espace est limité en mémoire. Il se trouve donc
simplement que 8.12 et/ou 8.0 et/ou 0.12 et/ou une des valeurs
intermédiaire dans un des registres du CPU ne sont pas représentables
dans le type en question, et c'est donc la valeur la plus proche
représentable qui est en fait mémorisée. C'est d'ailleurs pour des
raisons comme celles-ci qu'on utilise pas les doubles pour faire des
calculs banquaires par exemple.

Tu peux au choix travailler avec des entiers en virgule fixe (en
multipliant par exemple par 1000 et en replacant la virgule juste pour
l'affichage: 8120 - 800 = 120 -> 0.120) ou en utilisant des types
spécialement développés dans cette optique (en VB, Decimal ou Currency
par exemple)

Vincnet Guichard

Dim val1S As Double, val2S As Double
Dim val1C As Currency, val2C As Currency
Dim val1D As Variant, val2D As Variant 'Decimal est un sous-type variant
Dim val1L As Long, val2L As Long
val1S = 8.12
val2S = 8
val1C = 8.12
val2C = 8
val1D = CDec(8.12)
val2D = CDec(8)
val1L = 8.12 * 1000
val2L = 8 * 1000
MsgBox val1S - val2S
MsgBox val1C - val2C
MsgBox val1D - val2D
MsgBox (val1L - val2L) / 1000
Avatar
Merci beaucoup pour ces informations, je n'avais jamais remarqué ce
problème.



"Vincent Guichard" a écrit dans le message de
news: 466ea9b8$0$27397$
util a écrit :
Bonjour,

Je viens de remarquer un prbl dans mon programme, en faisant :

msgbox 8.12 - 8 j'ai 0.11999999999

Pour moi 8.12 - 8 = 0.12, visiblement c'est pas le cas de VB

Si quelqu'un a des infos sur le sujet ou une methode plus juste pour
calculer, je vous remercie d'avance.

Cordialement.

Damien



Bienvenue dans le monde des calculs numérique!

8.12 est par défaut converti en double. Le type double a une
représentation binaire en mémoire définie (dans une norme IEEE, mais je
sais plus son numéro). Cette représentation ne peux bien sur pas exprimer
_toutes_ les valeurs possibles, puisqu'il existe une infinité de valeurs
et l'espace est limité en mémoire. Il se trouve donc simplement que 8.12
et/ou 8.0 et/ou 0.12 et/ou une des valeurs intermédiaire dans un des
registres du CPU ne sont pas représentables dans le type en question, et
c'est donc la valeur la plus proche représentable qui est en fait
mémorisée. C'est d'ailleurs pour des raisons comme celles-ci qu'on utilise
pas les doubles pour faire des calculs banquaires par exemple.

Tu peux au choix travailler avec des entiers en virgule fixe (en
multipliant par exemple par 1000 et en replacant la virgule juste pour
l'affichage: 8120 - 800 = 120 -> 0.120) ou en utilisant des types
spécialement développés dans cette optique (en VB, Decimal ou Currency par
exemple)

Vincnet Guichard

Dim val1S As Double, val2S As Double
Dim val1C As Currency, val2C As Currency
Dim val1D As Variant, val2D As Variant 'Decimal est un sous-type variant
Dim val1L As Long, val2L As Long
val1S = 8.12
val2S = 8
val1C = 8.12
val2C = 8
val1D = CDec(8.12)
val2D = CDec(8)
val1L = 8.12 * 1000
val2L = 8 * 1000
MsgBox val1S - val2S
MsgBox val1C - val2C
MsgBox val1D - val2D
MsgBox (val1L - val2L) / 1000



Avatar
Jacques93
Bonjour util,
util a écrit :
Bonjour,

Je viens de remarquer un prbl dans mon programme, en faisant :

msgbox 8.12 - 8 j'ai 0.11999999999

Pour moi 8.12 - 8 = 0.12, visiblement c'est pas le cas de VB

Si quelqu'un a des infos sur le sujet ou une methode plus juste pour
calculer, je vous remercie d'avance.




Il faut effectuer l'opération avec des valeurs de type Currency
(entier scalaire compris entre – 922 337 203 685 477,5808 et
922 337 203 685 477,5807)

Ici par défaut VB effectue l'opération avec des valeurs de type double
(valeur en virgule flottante à double précision, comprise entre –
1,79769313486232E308 et – 4,94065645841247E-324 pour les valeurs
négatives et entre 4,94065645841247E-324 et 1,79769313486232E308 pour
les valeurs positives, et 0)

Donc au lieu de :

MsgBox 8.12 - 8

utiliser :

MsgBox CCur(8.12 - 8)


Voir aussi l'article de la FAQ :

<http://faq.vb.free.fr/index.php?question6>
--
Cordialement,

Jacques.
Avatar
Jacques93
Bonjour Vincent Guichard,
Vincent Guichard a écrit :
util a écrit :
Bonjour,

Je viens de remarquer un prbl dans mon programme, en faisant :

msgbox 8.12 - 8 j'ai 0.11999999999

Pour moi 8.12 - 8 = 0.12, visiblement c'est pas le cas de VB

Si quelqu'un a des infos sur le sujet ou une methode plus juste pour
calculer, je vous remercie d'avance.

Cordialement.

Damien




Bienvenue dans le monde des calculs numérique!

8.12 est par défaut converti en double. Le type double a une
représentation binaire en mémoire définie (dans une norme IEEE, mais je
sais plus son numéro). Cette représentation ne peux bien sur pas
exprimer _toutes_ les valeurs possibles, puisqu'il existe une infinité
de valeurs et l'espace est limité en mémoire. Il se trouve donc
simplement que 8.12 et/ou 8.0 et/ou 0.12 et/ou une des valeurs
intermédiaire dans un des registres du CPU ne sont pas représentables
dans le type en question, et c'est donc la valeur la plus proche
représentable qui est en fait mémorisée. C'est d'ailleurs pour des
raisons comme celles-ci qu'on utilise pas les doubles pour faire des
calculs banquaires par exemple.

Tu peux au choix travailler avec des entiers en virgule fixe (en
multipliant par exemple par 1000 et en replacant la virgule juste pour
l'affichage: 8120 - 800 = 120 -> 0.120) ou en utilisant des types
spécialement développés dans cette optique (en VB, Decimal ou Currency
par exemple)

Vincnet Guichard

Dim val1S As Double, val2S As Double
Dim val1C As Currency, val2C As Currency
Dim val1D As Variant, val2D As Variant 'Decimal est un sous-type variant
Dim val1L As Long, val2L As Long
val1S = 8.12
val2S = 8
val1C = 8.12
val2C = 8
val1D = CDec(8.12)
val2D = CDec(8)
val1L = 8.12 * 1000
val2L = 8 * 1000
MsgBox val1S - val2S
MsgBox val1C - val2C
MsgBox val1D - val2D
MsgBox (val1L - val2L) / 1000




Je n'ai vu ta réponse qu'après avoir posté la mienne. Juste une petite
précision : avec CDec, il faut écrire :

MsgBox CDec (8.2) - CDec(8)

alors qu'avec Ccur

MsgBox CCur(8.2 - 8)

donne le bon résultat. Par ailleurs, tout petit détail, je viens de
m'apercevoir que CDec n'est pas reconnu en tant que mot-clé (pas de
coloration syntaxique). Mystère ...

--
Cordialement,

Jacques.
Avatar
Vincent Guichard
> Par ailleurs, tout petit détail, je viens de
m'apercevoir que CDec n'est pas reconnu en tant que mot-clé (pas de
coloration syntaxique). Mystère ...



En effet, CDec ,'est pas un mot clef. c'est probablement parce que,
contrairement à Currency, Decimal n'est pas un type à part entière,
c'est un sous type de Variant (on ne peut pas faire de Dim D as Decimal)

Vincent Guichard
Avatar
andre.araste
Bonjour

Soustraction 8.12 - 8

Vous pouvez aussi utiliser l'instruction Format :

MsgBox Format(8.12 - 8,"0.00")
--
Bonne réception.

http://perso.orange.fr/andre.araste/
Membre du Club Win's: http://www.clubwins.org
Avertissement: Je ne vends rien.



<util> a écrit dans le message de news:


Bonjour,

Je viens de remarquer un prbl dans mon programme, en faisant :

msgbox 8.12 - 8 j'ai 0.11999999999

Pour moi 8.12 - 8 = 0.12, visiblement c'est pas le cas de VB

Si quelqu'un a des infos sur le sujet ou une methode plus juste pour
calculer, je vous remercie d'avance.

Cordialement.

Damien



Avatar
Jacques93
Vincent Guichard a écrit :
Par ailleurs, tout petit détail, je viens de m'apercevoir que CDec
n'est pas reconnu en tant que mot-clé (pas de coloration syntaxique).
Mystère ...



En effet, CDec ,'est pas un mot clef. c'est probablement parce que,
contrairement à Currency, Decimal n'est pas un type à part entière,
c'est un sous type de Variant (on ne peut pas faire de Dim D as Decimal)




Merci de la précision. A noter également que sous .Net le type Currency
(et CCur) n'est plus présent. Il est est donc prudent d'utiliser le type
Decimal et CDec, au cas où ...

D'autant plus que l'assistant de mise à niveau de VB6 vers VB.Net
convertit :

Msgbox CCur(8.12 - 8) ' OK en VB6

par :

MsgBox(CDec(8.12 - 8)) ' Erroné en VB6 et en VB.Net

--
Cordialement,

Jacques.
Avatar
Patrice Henrio
"andre.araste" a écrit dans le message de news:
466fabe5$0$27397$
Bonjour

Soustraction 8.12 - 8

Vous pouvez aussi utiliser l'instruction Format :

MsgBox Format(8.12 - 8,"0.00")
--
Bonne réception.

http://perso.orange.fr/andre.araste/
Membre du Club Win's: http://www.clubwins.org
Avertissement: Je ne vends rien.



<util> a écrit dans le message de news:


Bonjour,

Je viens de remarquer un prbl dans mon programme, en faisant :

msgbox 8.12 - 8 j'ai 0.11999999999

Pour moi 8.12 - 8 = 0.12, visiblement c'est pas le cas de VB

Si quelqu'un a des infos sur le sujet ou une methode plus juste pour
calculer, je vous remercie d'avance.

Cordialement.

Damien







Derrière tout cela il y a le nombre en tant qu'entité, sa valeur au sein du
processeur et se représentation à l'écran.
0.11999999999999999999999999999999999999999... (les .... signifient qu'il y
a autant de 9 que l'on souhaite) est une représentation décimale du nombre
réel 0.12. La précision de André Araste a le mérite d'insister sur la
représentation à l'écran ou ce qui revient au même la représentation du
nombre en tant que chaîne de caractères.
Cela me rappelle une anecdote, un professeur notait un test de 3 questions
sur 10. L'élève qui avait une bonne réponse se voyait attribué la note 3.33
(vous apprécierez déjà la précision de la notation). celui qui avait deux
bonnes réponses avait 6.66 et celui qui avait 3 bonnes réponses avait 10.
Un élève fit remarquer que normalement l'élève avec 2 bonnes réponses
devrait avoir 6.67 (le centième de point avait sûrement son importance) et
le professeur ne voulut pas en démordre indiquant que 2x3.33 donnait 6.66.
L'élève impertinent exigea alors d'avoir 9.99 qui correspond bien à 3x3.33.
L'histoire ne dit pas ce que fit le professeur ni s'il comprit ce que
l'élève cherchait à lui expliquer.