IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Erreur de calcul de la fonction Int() partie entiére d'un Nb en VB


Sujet :

Macros et VBA Excel

  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Février 2012
    Messages : 49
    Points : 18
    Points
    18
    Par défaut Erreur de calcul de la fonction Int() partie entiére d'un Nb en VB
    Bonjour,
    j'ai rencontré une erreur d'exécution de la fonction en VBA qui renvoi la partie entière d'un nombre que j'arrive pas à résoudre. je m'explique:
    soit le nombre suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    37,4*50/17 = 37,4/0,34 = 110,000
    (0,34 vaut 17/50). Il est évident que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Int(37,4*50/17) = Int(37,4/0,34) = 110
    Malheureusement à l'exécution de la fonction via VBA le résultat des deux expressions est différent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Int(37,4*50/17) renvoi 110 par contre Int(37,4/0,34) renvoi 109 ?
    Alors comme peut on résoudre se problème?
    Cordialement

  2. #2
    Expert éminent Avatar de jfontaine
    Homme Profil pro
    Contrôleur de Gestion
    Inscrit en
    Juin 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Contrôleur de Gestion

    Informations forums :
    Inscription : Juin 2006
    Messages : 4 754
    Points : 9 396
    Points
    9 396
    Par défaut
    Bonjour,

    Sur mon poste, les 2 instructions retournent 109
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MsgBox Int(37.4 * 50 / 17)
    MsgBox Int(37.4 / 0.34)
    Par contre, les lignes ci dessous retournent 110
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MsgBox Evaluate("37.4 * 50 / 17")
    MsgBox Evaluate("37.4 / 0.34")
    Je n'ai pas d'explications quand à la différence de résultat

  3. #3
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonjour,

    Les fonctions VBA Int() (tout comme Fix()) fond visiblement des erreurs d'arrondis.

    En complément de la solution de JFontaine, pour obtenir un arrondi répétable de la représentation du résultat d'une division sur un entier, il est également possible d'utiliser :
    Int(37.4 / 0.34 + 0.5)

  4. #4
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    Février 2010
    Messages
    8 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : Février 2010
    Messages : 8 505
    Points : 16 429
    Points
    16 429
    Par défaut
    Bonjour

    J'utilise parfois l'arrondi au nombre de décimales qui convient lors des divisions pour éviter ces écarts dus au calcul en virgule flottante.

  5. #5
    Membre expert
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2011
    Messages
    1 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 858
    Points : 3 974
    Points
    3 974
    Par défaut
    Bonjour,

    C’est d’autant plus cocasse que la fonction ENT renvoie bien 110 avec Cordialement.

    Pour relativiser, on peut quand même remarquer que Int ((37.4 * 50 / 17)+0.00000000000001) renvoie 110 (14eme décimale).

  6. #6
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Février 2012
    Messages : 49
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par jfontaine Voir le message
    Bonjour,

    Sur mon poste, les 2 instructions retournent 109
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MsgBox Int(37.4 * 50 / 17)
    MsgBox Int(37.4 / 0.34)
    Par contre, les lignes ci dessous retournent 110
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MsgBox Evaluate("37.4 * 50 / 17")
    MsgBox Evaluate("37.4 / 0.34")
    Je n'ai pas d'explications quand à la différence de résultat
    Essayé de retourner les valeurs des deux expressions sur une feuille EXCEL en créant une fonction personnalisée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Partie_entiére(x as variant) as variant
        Partie_entiére=Int(x)
    End Function
    Résultats : Partie_entiére(37.4 * 50 / 17) = 110 ; Partie_entiére(37.4 / 0.34) = 109 ?

  7. #7
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonjour,

    Ce que veut dire JFontaine, c'est que le résultat sans erreur peut être obtenu avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Partie_entiére(x As Variant) As Variant
            Partie_entiére = Evaluate("=INT(" & x & ")")  ' et non pas ENT() car nom de fonction Anglais
    End Function
    P.S : Les accents sont déconseillés pour le nom de fonctions.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Février 2012
    Messages : 49
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par gFZT82 Voir le message
    Bonjour,

    C’est d’autant plus cocasse que la fonction ENT renvoie bien 110 avec Cordialement.
    Bonjour,
    ça marche bien avec VBA mais que faire pour VB ?

  9. #9
    Expert éminent Avatar de jfontaine
    Homme Profil pro
    Contrôleur de Gestion
    Inscrit en
    Juin 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Contrôleur de Gestion

    Informations forums :
    Inscription : Juin 2006
    Messages : 4 754
    Points : 9 396
    Points
    9 396
    Par défaut
    ça marche bien avec VBA mais que faire pour VB ?
    Sur excel VB se nomme VBA

    Quelle différence fais tu entre les 2? (a moins que tu ne travailles pas sur excel)

  10. #10
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Février 2012
    Messages : 49
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par gFZT82 Voir le message
    Pour relativiser, on peut quand même remarquer que Int ((37.4 * 50 / 17)+0.00000000000001) renvoie 110 (14eme décimale).
    Bonjour,
    Si c'est bien Vraie cela veut dire que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WorksheetFunction.RoundDown(37.4  / 0.34, 2) = 109,99
    et par conséquent;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Int (37.4  / 0.34) = 109
    Malheureusement,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WorksheetFunction.RoundDown(37.4  / 0.34, n) = 110,00... pour n = 0 à 14
    et,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Int(WorksheetFunction.RoundDown(37.4  / 0.34, n)) = 110 pour n = 0 à 14
    Cordialement

    Citation Envoyé par jfontaine Voir le message
    Sur excel VB se nomme VBA

    Quelle différence fais tu entre les 2? (a moins que tu ne travailles pas sur excel)
    Bonjour,
    ENT() est une fonction qui s'exécute bien sous EXCEL mais j'arrive pas à l'exécutée en code VB sous EXCEL. Essayé la fonction personnalisée suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Partie_entiére(x As Double) As Double
    Partie_entiére = ENT(x)
    End Function

  11. #11
    Expert éminent Avatar de jfontaine
    Homme Profil pro
    Contrôleur de Gestion
    Inscrit en
    Juin 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Contrôleur de Gestion

    Informations forums :
    Inscription : Juin 2006
    Messages : 4 754
    Points : 9 396
    Points
    9 396
    Par défaut
    "ENT()" est une fonction (formule) excel (abréviation d'ENTIER). uniquement utilisable dans une cellule

    "INT()" est une instruction VBA (abréviation d'INTEGER)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Partie_entiére(x As Double) As Double
    Partie_entiére = Int(x)
    End Function

  12. #12
    Membre expert
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2011
    Messages
    1 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 858
    Points : 3 974
    Points
    3 974
    Par défaut
    Citation Envoyé par GOLDINGMAROC Voir le message
    Bonjour,
    Si c'est bien Vraie cela veut dire que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WorksheetFunction.RoundDown(37.4  / 0.34, 2) = 109,99
    et par conséquent;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Int (37.4  / 0.34) = 109
    Malheureusement,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WorksheetFunction.RoundDown(37.4  / 0.34, n) = 110,00... pour n = 0 à 14
    et,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Int(WorksheetFunction.RoundDown(37.4  / 0.34, n)) = 110 pour n = 0 à 14
    Cordialement
    Et pourtant les faits sont tétus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int(109.99999999999999)= 109
    int(109.999999999999999)= 110
    Cordialement.

  13. #13
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonjour,

    Par erreur j'ai utilisé la fonction VBA INT au sein de la fonction EVALUATE, au lieu de ENT.

    La solution qui devrait convenir et corrigée en post #8

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Partie_entiére(x As Variant) As Variant
        Partie_entiére = Evaluate("=ENT(" & x & ")")
    End Function

  14. #14
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Février 2012
    Messages : 49
    Points : 18
    Points
    18
    Par défaut
    Il n'y a pas d'erreur cet bien INT au lieu de ENT

  15. #15
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Re.

    Effectivement, comme la solution ne convenait pas, j'ai cru que ça venait de nom de l'appel de la fonction.
    Mais il est vrai qu'il faut traduire le nom des fonctions dans l'Evaluate.

    Du coup, je ne vois pas pourquoi l'utilisation de l'Evaluate ne répond pas au problème d'arrondi ?

  16. #16
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Février 2012
    Messages : 49
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par jfontaine Voir le message
    "ENT()" est une fonction (formule) excel (abréviation d'ENTIER). uniquement utilisable dans une cellule

    "INT()" est une instruction VBA (abréviation d'INTEGER)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Partie_entiére(x As Double) As Double
    Partie_entiére = Int(x)
    End Function
    Bonjour,
    Les fonctions (formules) d'EXCEL ne sont pas toutes prises en charge pour une utilisation sous VBA. Par exemple les formules MIN et MAX d'EXCEL peuvent être appelées par VBA moyennant les instructions suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WorksheetFunction.MIN() et WorksheetFunction.MAX()
    et il y a d'autres dans la liste (voir Aide VBA)
    A remarquer que : les fonctions appelantes de la liste en question ne sont pas définie par VBA c.à.d il n'existe pas de fonctions équivalentes spécifiques pour VBA comme ENT et INT au moins à ma connaissance.
    Cordialement

    Citation Envoyé par BlueMonkey Voir le message
    Re.

    Effectivement, comme la solution ne convenait pas, j'ai cru que ça venait de nom de l'appel de la fonction.
    Mais il est vrai qu'il faut traduire le nom des fonctions dans l'Evaluate.

    Du coup, je ne vois pas pourquoi l'utilisation de l'Evaluate ne répond pas au problème d'arrondi ?
    Bonjour,
    Si votre proposition répond bien au problème de l'arrondi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function Partie_entiére(x As Variant) As Variant
        Partie_entiére = Evaluate("=INT(" & x & ")")
    End Function
    Partie_entiére = 110 pour x = 37.4*50/17 et x = 37.4/0.34
    je vois pas où est ce qu'il est le problème ?

  17. #17
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonjour,

    L'utilisation de la fonction Evaluate pour faire appel à Excel (plûtot qu'aux fonctions VB) pour le calcul résout le problème d'arrondi.

    Si le problème restant est de comprendre pourquoi est-ce qu'a avec les instructions de code VB on a des erreurs de précision lors de la récupération
    de la partie entière. Ca doit être lié à la représentation binaire des nombres flottants.
    La valeur <110> en flottant ne correspond pas à <110> exactement , mais à la représentation binaire en puissance de 2 la plus proche.
    La valeur la plus proche pouvant majoré ou minoré la valeur recherchée.

    Pour 110. la valeur binaire doit être du type 109.9999999999. Du coup la partie entière donne 109.
    Si la représentation binaire de 110 était plutôt 110.00000000001, Int(110) retournerait bien 110.
    Mais là on atteint les limites du principe même de la représentation de valeur réelle sur un ordinateur.

    La fonction ENT d'Excel doit probablement faire des opérations supplémentaires à la simple récupération de la partie entière, pour corriger le problème d'arrondi.

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 102
    Points : 117
    Points
    117
    Par défaut
    Bonjour

    Pour compléter le message de BlueMonkey, quand on utilise des nombres il est préférable de déclarer la variable qui contient le nombre car les opérations réalisées donneront des résultats qui peuvent être différents. Le type qui pose le moins de problème est Currency mais il est limité par le nombre chiffre significatif .
    Le format double ou single sont des formats en notation scientifique
    documentation VBA
    Les variables de type Double (à virgule flottante en double précision) sont stockées sous la forme de nombres à virgule flottante de 64 bits (8 octets) IEEE dont la valeur est comprise entre -1,79769313486231E308 et -4,94065645841247E-324 pour les nombres négatifs et entre 4,94065645841247E-324 et 1,79769313486231E308 pour les positifs. Le caractère de déclaration de type Double est le signe #
    on observe que le nombre de chiffre significatif sera automatiquement limité.
    Code à tester
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Private Sub UserForm_Initialize()
    Dim nb1 As Double
    Dim nb2 As Double
    nb1 = 1222222222
    nb2 = 2
    TextBox1 = nb1 * nb1 - nb1 ^ nb2
    End Sub
    Les calculettes dans les années 80 avaient le même défaut 12*12-12^2 ne donnait pas 0.
    JP

  19. #19
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Février 2012
    Messages : 49
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par jp014 Voir le message
    Bonjour

    Pour compléter le message de BlueMonkey, quand on utilise des nombres il est préférable de déclarer la variable qui contient le nombre car les opérations réalisées donneront des résultats qui peuvent être différents. Le type qui pose le moins de problème est Currency mais il est limité par le nombre chiffre significatif .
    Le format double ou single sont des formats en notation scientifique
    documentation VBA

    on observe que le nombre de chiffre significatif sera automatiquement limité.
    Code à tester
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Private Sub UserForm_Initialize()
    Dim nb1 As Double
    Dim nb2 As Double
    nb1 = 1222222222
    nb2 = 2
    TextBox1 = nb1 * nb1 - nb1 ^ nb2
    End Sub
    Les calculettes dans les années 80 avaient le même défaut 12*12-12^2 ne donnait pas 0.
    JP
    Bonjour,
    Les doubles sont représentées par 15 chiffres après la virgule comme suit :
    Les variables de type Double (à virgule flottante en double précision) sont stockées sous la forme de nombres à virgule flottante de 64 bits (8 octets) IEEE dont la valeur est comprise entre -1,797693134862315E308 et -4,94066E-324 pour les nombres négatifs et entre 4,94066E-324 et 1,797693134862315E308 pour les positifs. Le caractère de déclaration de type Double est le signe #
    c'est ce que j'ai trouvé dans un manuel VB est ce Vraie ?
    de plus le 15éme chiffre est toujours arrondi automatiquement au 14éme chiffre par VB dans une feuille de code.
    par exemple si vous Ecrivez zaza = 1,797693134862315 dans VB automatiquement zaza est rectifier par = 1,79769313486232

Discussions similaires

  1. Utilisation de la Fonction Int() (partie entière)
    Par petiteabeille64 dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 09/04/2009, 14h40
  2. [Dates] Erreur de calcul avec la fonction mktime ?
    Par Xpertfly dans le forum Langage
    Réponses: 1
    Dernier message: 18/11/2008, 11h40
  3. Erreur de calcul avec la fonction log
    Par xav181 dans le forum C++
    Réponses: 8
    Dernier message: 07/04/2008, 15h08
  4. fonction avec partie entière
    Par KrusK dans le forum Mathématiques
    Réponses: 4
    Dernier message: 15/01/2008, 22h37
  5. de float à int : partie entière automatique ?
    Par stokastik dans le forum C
    Réponses: 16
    Dernier message: 22/08/2006, 16h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo