Gobillot
Messages postés3140Date d'inscriptionvendredi 14 mai 2004StatutMembreDernière intervention11 mars 201934 26 déc. 2005 à 23:01
toujours la même chose à rajouter
approximation d'accord:
5 peut être la valeur approchée de 3 à 2 unités près.
mais ici, puisqu'on fournit un paramètre, on demande une valeur approchée précise à 1/(10^2) près
je cite:
"j'ai dit "La fonction Roundinf renvoie une valeur TOUJOURS INFERIERE à n"
on devrait obtenir alors -1 < 0 < 1 à l'unité près ?
ben non c'est pas le cas, parfois on peut avoir l'égalité.
- ce que dit Violent_ken:
p < x < p + 1 (il faudrait p + 2 dans certain cas)
- ce que fait la fonction:
1er cas: p <= x < p + 1
2eme cas: p < x <= p + 1
- ce que j'aurais préféré:
p <= x <= p + 1
- on peut remarquer que lorsqu'on fait les calculs intermédiaires
on n'a pas les mêmes résultats:
Public Function Roundinf(n As String, e As Long) As String
dim temp As Double
temp = (10 ^ e) * n
Roundinf = Int(temp) / (10 ^ e)
End Function
ca qui me fait dire, que le résultat obtenu par la Fonction, n'est pas voulu mais est suite a des erreurs de calcul étranges (mais peut être explicables, si quelqu'un peut ?) de Vb.
Rappel:
Int(2.3 * 10) donne 22
Int(2.4 * 10) donne 23
Int(2.15 * 100) donne 214
mais:
(2.15 * 100) donne 215
Int(215) donne 215
cs_Julien39
Messages postés6414Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention29 juillet 2020372 24 déc. 2005 à 20:43
Non ce n'est pas du tout ce que je voulais dire, je ne prennais cet exemple que por expliquer que l'approximation peut également être très grossiere et ce n'est pas pour cela que ce n'est pas une bonne appproximation.
Je ne parlais que d'un cas isolé sans prétendre que cette approxiamtion soit bonne...
Il faut sortir ne reste pas devant ton PC un soir de réveillon de Noël!!!!
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 24 déc. 2005 à 20:27
Salut !
Gobillot ==> j'ai dit "La fonction Roundinf renvoie une valeur TOUJOURS INFERIERE à n".
Je l'ai cité entre guillemets, c'est parce que je le tire directement des commentaires de la source ! Le but des 2 fonctions n'est (pardonnez moi si je fait erreur, mais c'est ce que j'ai compris) pas de faire forcément des arrondis par défaut/excès, mais de donner des valeurs strictement inférieures/supérieures. C'est la source qui le dit !
Je suis tout à fait d'accord qu'une utilisation normale doit donner le résultat que tu attends, Gobillot, mais ce n'est peut être pas (ce n'est pas , si j'ai bien compris) forcément le but des deux fonctions.
Julien39 ==> "Comme 1 est une bonne valeur approchée de 0".
Attention ! On ne parle pas de 0 comme de n'importe quel réel.
On ne peut pas, par exemple, dire qu'au voisinage de 0 ln(1+x) est équivalent à 0.
"Arrondir à 0" est donc à "prendre avec des pincettes"
@+
Gobillot
Messages postés3140Date d'inscriptionvendredi 14 mai 2004StatutMembreDernière intervention11 mars 201934 24 déc. 2005 à 15:04
oui mais le résultat est différent suivant la valeur:
Roundinf (0.2,1) ==> 0.2
Roundsup (0.2,1) ==> 0.3
donc 0.2 <= 0.2 < 0.3
Roundinf (1.2,1) ==> 1.1
Roundsup (1.2,1) ==> 1.2
donc 1.1 < 1.2 <= 1.2
c'est pas logique, parfois c'est la valeur inférieur qui donne l'égalité, parfois c'est la valeur supérieure, et ceci de façon aléatoire.
contrairement a ce que dit Violent_ken/
"La fonction Roundinf renvoie une valeur TOUJOURS INFERIERE à n et de manière analogue pour RoundSup."
exemple:
pour savoir le nombre de secteurs occupés par un fichier, j'ai besoin de connaître la valeur par excès. pour un multiple de 512 octets la fonction doit renvoyer l'égalité et non pas la valeur supérieure, j'ai pas besoin de secteurs supplémentaires.
Julien39 >>
comme tu as mis les fonctions dans un module on pourrait penser quelles sont faites pour des calculs d'arrondis, par défaut ou par excès, le mot "Round" prétant à confusion.
pour des valeurs où il y a l'égalité, donc pas de décimales à supprimer, le résultat est impévisible:
0.5 <= 0.5 < 0.6 mais 0.5 < 0.6 <= 0.6
- tous ces problèmes viennent des calculs avec du Double
alors supprimons les.
en convertissant le Double en décimal, on a plus d'erreurs.
Int() à la place de Fix(à permet d'être compatible avec les
nombres négatifs.
Private Function Roundinf(n As Double, e As Long) As Double
Dim ex As Double
ex = 10 ^ e
Roundinf = Int(CDec(n) * ex) / ex
End Function
- pour la fonction Roundsup, je vois pas d'autres possibilités
que de tester s'il faut ajouter 1 ou pas.
Private Function Roundsup(n As Double, e As Long) As Double
Dim ex As Double
Dim x As Variant
Dim z As Double
ex = 10 ^ e
x = CDec(n) * ex
z = Fix(x)
If z < x Then z = z + 1
Roundsup = z / ex
End Function
cs_Julien39
Messages postés6414Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention29 juillet 2020372 24 déc. 2005 à 14:28
Tout ces résultats sont normaux, Roundsup(0,0) retourne une valeur approchée de 0 avec 0 chiffres après la virgule, donc la valeur retournée est le plus petit entier strictement supérieur à 0 c'est 1. Idem pour Roundinf(0.3,1) qui renvoi le plus grand nombre à 1 chiffre après la virgule.
Pour la dernière remarque elle me semble assez étrange sachant que la fonction Roundapp() est (lorsqu'elle fonctionne) totalement équivalente à la fonction Round() de VB6.
Dernière remarque qu'est qu'un arrondi, si je dit que 3 est une valeur approchée de pi c'est vrai même si il existe de meilleures valeurs, même 5 est une bonne valeur approchée de pi.
Ce n'est cependant pas satisfaisant j'en convient. Pour pouvoir dire si une valeur approchée est bonne il faut donner un degré à 1 près 3 est une bonne valeur approchée de pi
Comme 1 est une bonne valeur approchée de 0
Ce qui est vrai à 1 près n'est pas vrai à 0.1 près
À 0,1 près 0.2 est une bonne valeur approchée de 0.3
En bref tout n'est qu'une question de tolérance d'erreur.
Gobillot
Messages postés3140Date d'inscriptionvendredi 14 mai 2004StatutMembreDernière intervention11 mars 201934 24 déc. 2005 à 13:32
heu non !
Roundinf doit renvoyer une valeur inférieure ou égale
Roundsup doit renvoyer une valeur supérieure ou égale
l'arrondi de zéro ne sera jamais 1
Roundsup (0,0) => 1 ???? me semble étrange
l'arondi de 0.3 ne sera jamais 0.2
Roundinf (0.3,1) => 0.2 ????
ces fonctions renvoient bien une valeur inférieure ou supérieure, sauf pour les valeurs négatives où là c'est totalement faux, mais ne peuvent en aucun cas servir comme fonctions d'arrondi.
cs_Julien39
Messages postés6414Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention29 juillet 2020372 24 déc. 2005 à 13:20
Je vais reprendre ce code et suivre vos conseils, le type string n'est en effet pas justifié.
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 24 déc. 2005 à 12:54
Salut.
Je me permet de faire aussi quelques remarques :
-je ne comprend pas non plus l'utilisation du type string, qui d'ailleurs renvoie une erreur
-petites explications pour la concaténation :
msgbox "az" & "er" est possible
msgbox "az" + "er" est aussi possible, puisque les deux éléments sont des string
msgbox "az" & 5 est possible
msgbox "az" + 5 est IMPOSSIBLE (il faut mettre des guillemets pour que çà marche avec un +)
Sinon, utiliser msgbox "az" + str$(5) mais attention, str$ créé un espace.
-l'encadrement de 12.22,2 renvoie 12.19<12.2<12.2 Attention aux bornes ! Il faut alors mettre <= ou bien mettre <12.21
Gobillot ==> je me permet de répondre à la place de Julien39 : RoundInf et RoundSup ne sont pas les arrondis par défaut/exces.
"La fonction Roundinf renvoie une valeure TOUJOURS INFERIERE à n" et de manière analogue pour RoundSup.
@+
Gobillot
Messages postés3140Date d'inscriptionvendredi 14 mai 2004StatutMembreDernière intervention11 mars 201934 23 déc. 2005 à 12:00
- je corrige ma dernière remarque:
Int(0.03 * 100) / 100 donne 0.02
Int(2.15 * 100) / 100 donne 2.14
mais l'erreur intervient avant la division:
Int(0.03 * 100) donne 2
Int(2.15 * 100) donne 214
Gobillot
Messages postés3140Date d'inscriptionvendredi 14 mai 2004StatutMembreDernière intervention11 mars 201934 23 déc. 2005 à 11:55
- Les calculs avec des chaînes n'apportent rien et pénalisent
les performances.
Tout calcul avec chaîne passe par une conversion en Double.
Dim s As String
Dim x As Variant
s = 2
MsgBox TypeName(s + 2) ' --> Double
x = 2
MsgBox TypeName(x) ' --> Integer
x = s + 0
MsgBox TypeName(x) ' --> Double
- Pour concaténer des chaînes, on utilise "&" et non pas "+"
n = n & "0"
- Fonction Roundinf
l'arrondi par défaut de 0,03 n'est pas 0.02
- Fonction Roundsup
l'arrondi par excès de 0.01 n'est pas 0.02
- Les nombres négatifs ne sont pas traités
faire la différence avec Fix() et Int()
l'arrondi de -2.141 est:
inférieur -2.15
supérieur -2.14
- La Fonction Roundapp est bien trop compliquée
Private Function Roundapp(n As Double, e As Long) As Double
Dim ex As Double
ex = 10 ^ e
Roundapp = Int(CDec(n) * ex + 0.5) / ex
End Function
- désolé de toutes ses remarques qui j'espèrent ne te vexeront pas.
il faut prendre en compte les défauts de calcul de VB:
Int(0.03 * 100) donne 0.02
Int(2.15 * 100) donne 2.14
cs_Julien39
Messages postés6414Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention29 juillet 2020372 23 déc. 2005 à 09:24
La source est modifiée et fonctionne (enfin j'espere), merci de votre aide
Gobillot
Messages postés3140Date d'inscriptionvendredi 14 mai 2004StatutMembreDernière intervention11 mars 201934 23 déc. 2005 à 01:28
- il y a des problèmes !!!!
Roundinf(2.15, 2) renvoit 2.14 au lieu de 2.15
Roundsup(2.14, 2) renvoit 2.15 au lieu de 2.14
Roundapp(2.14, 2) se plante
Roundapp(2.141, 2) renvoit 214.09
- pourquoi travailler en String et pas directement en Double ?
cs_Jack
Messages postés14006Date d'inscriptionsamedi 29 décembre 2001StatutModérateurDernière intervention28 août 201579 23 déc. 2005 à 01:25
Salut
Ca pourra peut-être servir ...
Tu aurais plutôt dû mettre ça dans la section maths.
Corrige le problème de l'utilisation de n = entier (fonction Instr ne renvoie rien puisque pas de virgule -> erreur)
26 déc. 2005 à 23:01
approximation d'accord:
5 peut être la valeur approchée de 3 à 2 unités près.
mais ici, puisqu'on fournit un paramètre, on demande une valeur approchée précise à 1/(10^2) près
je cite:
"j'ai dit "La fonction Roundinf renvoie une valeur TOUJOURS INFERIERE à n"
on devrait obtenir alors -1 < 0 < 1 à l'unité près ?
ben non c'est pas le cas, parfois on peut avoir l'égalité.
- ce que dit Violent_ken:
p < x < p + 1 (il faudrait p + 2 dans certain cas)
- ce que fait la fonction:
1er cas: p <= x < p + 1
2eme cas: p < x <= p + 1
- ce que j'aurais préféré:
p <= x <= p + 1
- on peut remarquer que lorsqu'on fait les calculs intermédiaires
on n'a pas les mêmes résultats:
Public Function Roundinf(n As String, e As Long) As String
dim temp As Double
temp = (10 ^ e) * n
Roundinf = Int(temp) / (10 ^ e)
End Function
ca qui me fait dire, que le résultat obtenu par la Fonction, n'est pas voulu mais est suite a des erreurs de calcul étranges (mais peut être explicables, si quelqu'un peut ?) de Vb.
Rappel:
Int(2.3 * 10) donne 22
Int(2.4 * 10) donne 23
Int(2.15 * 100) donne 214
mais:
(2.15 * 100) donne 215
Int(215) donne 215
24 déc. 2005 à 20:43
Je ne parlais que d'un cas isolé sans prétendre que cette approxiamtion soit bonne...
Il faut sortir ne reste pas devant ton PC un soir de réveillon de Noël!!!!
24 déc. 2005 à 20:27
Gobillot ==> j'ai dit "La fonction Roundinf renvoie une valeur TOUJOURS INFERIERE à n".
Je l'ai cité entre guillemets, c'est parce que je le tire directement des commentaires de la source ! Le but des 2 fonctions n'est (pardonnez moi si je fait erreur, mais c'est ce que j'ai compris) pas de faire forcément des arrondis par défaut/excès, mais de donner des valeurs strictement inférieures/supérieures. C'est la source qui le dit !
Je suis tout à fait d'accord qu'une utilisation normale doit donner le résultat que tu attends, Gobillot, mais ce n'est peut être pas (ce n'est pas , si j'ai bien compris) forcément le but des deux fonctions.
Julien39 ==> "Comme 1 est une bonne valeur approchée de 0".
Attention ! On ne parle pas de 0 comme de n'importe quel réel.
On ne peut pas, par exemple, dire qu'au voisinage de 0 ln(1+x) est équivalent à 0.
"Arrondir à 0" est donc à "prendre avec des pincettes"
@+
24 déc. 2005 à 15:04
Roundinf (0.2,1) ==> 0.2
Roundsup (0.2,1) ==> 0.3
donc 0.2 <= 0.2 < 0.3
Roundinf (1.2,1) ==> 1.1
Roundsup (1.2,1) ==> 1.2
donc 1.1 < 1.2 <= 1.2
c'est pas logique, parfois c'est la valeur inférieur qui donne l'égalité, parfois c'est la valeur supérieure, et ceci de façon aléatoire.
contrairement a ce que dit Violent_ken/
"La fonction Roundinf renvoie une valeur TOUJOURS INFERIERE à n et de manière analogue pour RoundSup."
exemple:
pour savoir le nombre de secteurs occupés par un fichier, j'ai besoin de connaître la valeur par excès. pour un multiple de 512 octets la fonction doit renvoyer l'égalité et non pas la valeur supérieure, j'ai pas besoin de secteurs supplémentaires.
Julien39 >>
comme tu as mis les fonctions dans un module on pourrait penser quelles sont faites pour des calculs d'arrondis, par défaut ou par excès, le mot "Round" prétant à confusion.
pour des valeurs où il y a l'égalité, donc pas de décimales à supprimer, le résultat est impévisible:
0.5 <= 0.5 < 0.6 mais 0.5 < 0.6 <= 0.6
- tous ces problèmes viennent des calculs avec du Double
alors supprimons les.
en convertissant le Double en décimal, on a plus d'erreurs.
Int() à la place de Fix(à permet d'être compatible avec les
nombres négatifs.
Private Function Roundinf(n As Double, e As Long) As Double
Dim ex As Double
ex = 10 ^ e
Roundinf = Int(CDec(n) * ex) / ex
End Function
- pour la fonction Roundsup, je vois pas d'autres possibilités
que de tester s'il faut ajouter 1 ou pas.
Private Function Roundsup(n As Double, e As Long) As Double
Dim ex As Double
Dim x As Variant
Dim z As Double
ex = 10 ^ e
x = CDec(n) * ex
z = Fix(x)
If z < x Then z = z + 1
Roundsup = z / ex
End Function
24 déc. 2005 à 14:28
Pour la dernière remarque elle me semble assez étrange sachant que la fonction Roundapp() est (lorsqu'elle fonctionne) totalement équivalente à la fonction Round() de VB6.
Dernière remarque qu'est qu'un arrondi, si je dit que 3 est une valeur approchée de pi c'est vrai même si il existe de meilleures valeurs, même 5 est une bonne valeur approchée de pi.
Ce n'est cependant pas satisfaisant j'en convient. Pour pouvoir dire si une valeur approchée est bonne il faut donner un degré à 1 près 3 est une bonne valeur approchée de pi
Comme 1 est une bonne valeur approchée de 0
Ce qui est vrai à 1 près n'est pas vrai à 0.1 près
À 0,1 près 0.2 est une bonne valeur approchée de 0.3
En bref tout n'est qu'une question de tolérance d'erreur.
24 déc. 2005 à 13:32
Roundinf doit renvoyer une valeur inférieure ou égale
Roundsup doit renvoyer une valeur supérieure ou égale
l'arrondi de zéro ne sera jamais 1
Roundsup (0,0) => 1 ???? me semble étrange
l'arondi de 0.3 ne sera jamais 0.2
Roundinf (0.3,1) => 0.2 ????
ces fonctions renvoient bien une valeur inférieure ou supérieure, sauf pour les valeurs négatives où là c'est totalement faux, mais ne peuvent en aucun cas servir comme fonctions d'arrondi.
24 déc. 2005 à 13:20
24 déc. 2005 à 12:54
Je me permet de faire aussi quelques remarques :
-je ne comprend pas non plus l'utilisation du type string, qui d'ailleurs renvoie une erreur
-petites explications pour la concaténation :
msgbox "az" & "er" est possible
msgbox "az" + "er" est aussi possible, puisque les deux éléments sont des string
msgbox "az" & 5 est possible
msgbox "az" + 5 est IMPOSSIBLE (il faut mettre des guillemets pour que çà marche avec un +)
Sinon, utiliser msgbox "az" + str$(5) mais attention, str$ créé un espace.
-l'encadrement de 12.22,2 renvoie 12.19<12.2<12.2 Attention aux bornes ! Il faut alors mettre <= ou bien mettre <12.21
Gobillot ==> je me permet de répondre à la place de Julien39 : RoundInf et RoundSup ne sont pas les arrondis par défaut/exces.
"La fonction Roundinf renvoie une valeure TOUJOURS INFERIERE à n" et de manière analogue pour RoundSup.
@+
23 déc. 2005 à 12:00
Int(0.03 * 100) / 100 donne 0.02
Int(2.15 * 100) / 100 donne 2.14
mais l'erreur intervient avant la division:
Int(0.03 * 100) donne 2
Int(2.15 * 100) donne 214
23 déc. 2005 à 11:55
les performances.
Tout calcul avec chaîne passe par une conversion en Double.
Dim s As String
Dim x As Variant
s = 2
MsgBox TypeName(s + 2) ' --> Double
x = 2
MsgBox TypeName(x) ' --> Integer
x = s + 0
MsgBox TypeName(x) ' --> Double
- Pour concaténer des chaînes, on utilise "&" et non pas "+"
n = n & "0"
- Fonction Roundinf
l'arrondi par défaut de 0,03 n'est pas 0.02
- Fonction Roundsup
l'arrondi par excès de 0.01 n'est pas 0.02
- Les nombres négatifs ne sont pas traités
faire la différence avec Fix() et Int()
l'arrondi de -2.141 est:
inférieur -2.15
supérieur -2.14
- La Fonction Roundapp est bien trop compliquée
Private Function Roundapp(n As Double, e As Long) As Double
Dim ex As Double
ex = 10 ^ e
Roundapp = Int(CDec(n) * ex + 0.5) / ex
End Function
- désolé de toutes ses remarques qui j'espèrent ne te vexeront pas.
il faut prendre en compte les défauts de calcul de VB:
Int(0.03 * 100) donne 0.02
Int(2.15 * 100) donne 2.14
23 déc. 2005 à 09:24
23 déc. 2005 à 01:28
Roundinf(2.15, 2) renvoit 2.14 au lieu de 2.15
Roundsup(2.14, 2) renvoit 2.15 au lieu de 2.14
Roundapp(2.14, 2) se plante
Roundapp(2.141, 2) renvoit 214.09
- pourquoi travailler en String et pas directement en Double ?
23 déc. 2005 à 01:25
Ca pourra peut-être servir ...
Tu aurais plutôt dû mettre ça dans la section maths.
Corrige le problème de l'utilisation de n = entier (fonction Instr ne renvoie rien puisque pas de virgule -> erreur)