Bonjour à tous,
Quelqu'un aurait-il une explication, voir une solution à ce problème :
CDbl(CSng("0,3")) = 0,300000011920929 et pas 0,3
CDbl(CSng("567,27")) = 567,27001953125 et pas 567,27
Cela ressemble à un bug de VB6, non ?
Merci d'avance
Bonjour à tous,
Quelqu'un aurait-il une explication, voir une solution à ce problème :
CDbl(CSng("0,3")) = 0,300000011920929 et pas 0,3
CDbl(CSng("567,27")) = 567,27001953125 et pas 567,27
Cela ressemble à un bug de VB6, non ?
Merci d'avance
Le plus difficile pour trouver une bonne réponse, c'est déjà de trouver la bonne question.
je pense que s'est dans l'ordre de la conversion, comme sa le resultat est bon
mais pourquoi , moi je ne sais pas.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Label1 = CSng(CDbl("0,3")) '= 0,3 Label2 = CSng(CDbl("567,27")) '= 567,27
Soyez sympa, pensez -y
Balises[CODE]...[/CODE]
Balises[CODE=NomDuLangage]...[/CODE] quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
Balises[C]...[/C] code intégré dans une phrase.
Balises[C=NomDuLangage]...[/C] code intégré dans une phrase quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
Le bouton en fin de discussion, quand vous avez obtenu l'aide attendue.
......... et pourquoi pas, pour remercier, un pour celui/ceux qui vous ont dépannés.
👉 → → Ma page perso sur DVP ← ← 👈
Effectivement, mais mon objectif est de transformer un Single en Double et pas l'inverse...Envoyé par ProgElecT
Au moins, je sais maintenant que cela ne vient pas mon ordinateur.
Merci quand même
Le plus difficile pour trouver une bonne réponse, c'est déjà de trouver la bonne question.
C'est par ce que tu commence par transformer une chaîne (String) en Single, puis ce Single en Double... Plus il y a de manipulations plus il s'accumule d'erreurs. Si tu convertis directement
tu n'as plus de problème!
Code : Sélectionner tout - Visualiser dans une fenêtre à part Debug.Print CDbl(0.3)
Si tu cherches à convertir en Double le contenu d'un TextBox :
Voilà!
Code : Sélectionner tout - Visualiser dans une fenêtre à part Debug.Print CDbl(Val(Text1.Text))
- Pour les nouveaux : Mode d'emploi et aide aux nouveaux
- et impérativement les règles du forum. Histoire de garder une ambiance amicale.
- Noubliez pas les balises de Code pour vos listings : bouton # de l'éditeur. Et n'oubliez pas non plus de bouton
- Cours Excel - FAQ Excel - Forum Excel - Cours VBA - Cours complet VBA Excel
Le code suivant était un exemple pour mettre en évidence le problème :
Je cherche "simplement" à convertir un Single en Double.
Code : Sélectionner tout - Visualiser dans une fenêtre à part CDbl(CSng("0,3"))
Je sais simplement, qu'avant, quelque part dans le déroulement du programme, ce Single provient d'une zone de texte.
Le programme étant vaste, je dois prendre le single tel qu'il est sans me soucier de sa provenance, ni de son vécu.
Je suppose que le programme n'est pas en cause car CDbl(CSng("0,3")) renvoi 0,300000011920929 dans la fenêtre d'éxécution.
Le plus difficile pour trouver une bonne réponse, c'est déjà de trouver la bonne question.
On peut voir comment la fonction de conversion est déclarée, décrite, avec ses paramètres... ?
- Pour les nouveaux : Mode d'emploi et aide aux nouveaux
- et impérativement les règles du forum. Histoire de garder une ambiance amicale.
- Noubliez pas les balises de Code pour vos listings : bouton # de l'éditeur. Et n'oubliez pas non plus de bouton
- Cours Excel - FAQ Excel - Forum Excel - Cours VBA - Cours complet VBA Excel
C'est le problème des calculs avec des virgules flottantes je crois, si je ne dis pas de betise, ca tient plus du processeur que de VB.
En tout cas tu peux palier à ton pb en mettant par exemple :
Pas terrible terrible, mais ça fonctionne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part CDbl(Format(CSng(0.3), "0.0000000000000000"))
Pour VB6 : N'oubliez pas d'aller voir la FAQ et les Tutoriels
Vous trouvez une reponse particulierement utile ? Votez pour !
Je pense que le problème est spécifique à la conversion Single vers Double car :Je pense que je vais adopter cette solution ici faute de mieux...
Code : Sélectionner tout - Visualiser dans une fenêtre à part CDbl(CStr(CSng("0,3"))) = 0,3
Ce qui m'inquiète c'est pour tout le reste du programme où je n'est pas encore détecté le problème...
Le plus difficile pour trouver une bonne réponse, c'est déjà de trouver la bonne question.
Envoyé par NajdarCar, si j'ai bien compris, tu essaie de créer une fonction de conversion qui soit applicable à une valeur, peu importe sa provenance et son type, tout en conservant un format déterminé.Envoyé par zazaraignée
- Pour les nouveaux : Mode d'emploi et aide aux nouveaux
- et impérativement les règles du forum. Histoire de garder une ambiance amicale.
- Noubliez pas les balises de Code pour vos listings : bouton # de l'éditeur. Et n'oubliez pas non plus de bouton
- Cours Excel - FAQ Excel - Forum Excel - Cours VBA - Cours complet VBA Excel
En essayant de faire court :
Je stocke dans une property d'une classe des valeurs provenant de diverses sources et de types différents:
- saisies à l'écran et bases de données.
- Single, Double, Long, ...
Je sais que ces valeurs sont toujours des numériques, j'ai donc choisi Double pour être sûr que tous les types "tiennent".
Le problème se pose quand j'affecte à cette property une valeur de type Single.
Pour que cela fonctionne correctement :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 Private mValeur(1 To 4) As Double Public Property Get Valeur(ByVal Index As Integer) As Double Valeur = mValeur(Index) End Property Public Property Let Valeur(ByVal Index As Integer, ByVal vNewValue As Double) mValeur(Index) = vNewValue End Property
Cela n'est pas terrible, et l'utilisation d'un Variant ne me plait pas
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Private mValeur(1 To 4) As Double Public Property Get Valeur(ByVal Index As Integer) As Variant Valeur = mValeur(Index) End Property Public Property Let Valeur(ByVal Index As Integer, ByVal vNewValue As Variant) If TypeName(vNewValue) = "Single" Then mValeur(Index) = CDbl(CStr(vNewValue)) Else mValeur(Index) = CDbl(vNewValue) End If End Property
Le plus difficile pour trouver une bonne réponse, c'est déjà de trouver la bonne question.
Heu... Un currency ne tiendra pas dans un Double.
Pour le reste, je suis lagruée! Je m'attendais à voir une Fonction et tu m'envoies une Propriété.
Il te sera difficile de traiter n'importe quoi venant de n'importe où sans provoquer des erreurs!
- Pour les nouveaux : Mode d'emploi et aide aux nouveaux
- et impérativement les règles du forum. Histoire de garder une ambiance amicale.
- Noubliez pas les balises de Code pour vos listings : bouton # de l'éditeur. Et n'oubliez pas non plus de bouton
- Cours Excel - FAQ Excel - Forum Excel - Cours VBA - Cours complet VBA Excel
Ben au contraire je trouve l'idée bonne moi
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Public Property Let Valeur(ByVal Index As Integer, ByVal vNewValue As Variant) Dim strTemp as string Dim iPosit as Integer strTemp = Cstr(vNewValue) iPosit = instrRev(strTemp,",") if iPosit then Mid(strTemp,iPosit,1)= "." end if mValeur(Index) = CDbl(strTemp) End Property
En général, on ne demande de conseils que pour ne pas les suivre ou, si on les a suivis, reprocher à quelqu'un de les avoir donnés
(ALEXANDRE DUMAS)
N'hésitez pas à visiter ma page de contributions
Le problème vient de la conversion d'un single en double et cela ne vient pas du processeur, mais bien de VB.
Les nombres réels ou flottants sont décomposés en trois parties :
- S : le signe du nombre ;
- M : la mantisse ou significande ;
- E : l'exposant.
En faisant varier E, on fait "flotter" la virgule, d'où l'appellation de nombre flottant.
Regardons comment sont codé en binaire les nombres réel ou flottants :
Désignation Taille Signe Exposant Mantisse
Single 32 bits 1 bit 8 bits 23 bits
Double 64 bits 1 bit 11 bits 52 bits
Pour retrouver la valeur d'un nombre en simple précision, il faut faire :
(-1)^S*(1+M)*2^(E-127)
Ou, pour les nombres en double précision :
(-1)^S*(1+M)*2^(E-1023)
Si bien que si l'on représente notre nombre (1.1) en binaire, on obtient les représentations suivantes :
0011 1111 1000 1100 1100 1100 1100 1101 (3F 8C CC CD)
et
0011 1111 1111 0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010 (3F F1 99 99 99 99 99 9A)
Hors pour des raison de rapidité, Visual Basic ne recalcul ni l'exposant ni la mantisse lors d'une conversion d'un single en double, mais se contente de rajouter trois 1 à la fin de l'exposant et des 0 à la fin de la mantisse.
Notre 1,1 (single) converti en double devient donc :
0011 1111 1111 0001 1001 1001 1001 1001 1010 0000 0000 0000 0000 0000 0000 0000 (3F F1 99 99 A0 00 00 00)
Si l'on exprime ce nombre en décimale on obtient 1,1000000238418580. Ce qui n'est plus tout à fait 1,1.
La multiplication par 2 peut se résumer par l'adition de 1 à l'exposant.
0100 0000 0000 0001 1001 1001 1001 1001 1010 0000 0000 0000 0000 0000 0000 0000
40019999a0000000
Ce qui donne 2.2000000476837160 en décimal.
Belle démonstration
En général, on ne demande de conseils que pour ne pas les suivre ou, si on les a suivis, reprocher à quelqu'un de les avoir donnés
(ALEXANDRE DUMAS)
N'hésitez pas à visiter ma page de contributions
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager