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 :

Problème avec fonction Int() [XL-2007]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut Problème avec fonction Int()
    Bonjour,
    voici le code qui me pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ligne = 0
    Dim x As Double 
    For x = 1 To 2 Step 0.001
            If (x * 1000 = Int(x * 1000)) Then
                Cells(ligne, 1).Value = x
                ligne = ligne + 1
             End If
    Next
    Ce code donne comme premiers résultats :
    1
    1,002
    1,004
    1,006
    ...
    1,024
    1,025
    1,026
    ...

    Pourquoi entre 1 et 1,024 le résultat va-t-il de 0,002 en 0,002 (au lieu de 0,001 en 0,001) alors qu'à partir de 1,025 ça fonctionne normalement ???

    (ce code ne semble pas avoir de sens mais c'est parce que je l'ai simplifié. J'ai besoin de faire ce test : If (x * 1000 = Int(x * 1000)) car mon but est de récupérer les valeurs qui n'ont que 3 décimales alors si vous avez d'autres suggestions...)

    Merci pour votre aide !

    PS : on peut résumer le problème ainsi : pourquoi Int(1.009*1000)=1008 ?

  2. #2
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 324
    Par défaut
    Ce truc de fou... Peut-être un problème d'arrondi. Pour contourner le problème, mieux vaut faire la différence inférieure à un nombre proche de zéro:

    Citation Envoyé par jgfa9 Voir le message
    Bonjour,
    voici le code qui me pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ligne = 0
    Dim x As Double 
    For x = 1 To 2 Step 0.001
    'On prend 0.00001 mais on pourrait prendre 0.001
            If (x * 1000 - Int(x * 1000) <= 0.00001) Then
                Cells(ligne, 1).Value = x
                ligne = ligne + 1
             End If
    Next

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut
    Merci pour la réponse mais ça ne fonctionne pas car :

    x * 1000 - Int(x * 1000) vaut 0,9999999999...89 pour x=1.001

    Comment explique-t-on un tel fonctionnement ??

  4. #4
    Expert éminent Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Par défaut
    à essayer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Dim x As Double, y As Double
    Dim Ligne As Integer
    For x = 0 To 1000
        y = 1 + x / 1000
        If (1000 * y - Int(1000 * y)) < 1 Then  'au
            Ligne = Ligne + 1
            Cells(Ligne, 1).Value = y
         End If
    Next

  5. #5
    Inactif  
    Profil pro
    Inscrit en
    Février 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 517
    Par défaut
    salut

    Excel a quelquefois besoin de se faire forcer la main...
    Exemple ;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim x As Double, x1 As Double
    x = 1.001
    x1 = Val(Format(x * 1000, "#0")) ' on force ici la main
    MsgBox "x1 " & x1
    MsgBox (x1 * 1000) - Int(x1 * 1000)
    MsgBox x1 * 1000 - Int(x1 * 1000)

  6. #6
    pgz
    pgz est déconnecté
    Expert confirmé Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Par défaut
    Bonsoir.

    Il y a souvent des valeurs approchées dans les opérations avec les variables de type réel. Ici il est probable que 0,001 s'exprime en base 2 par un très grand nombre de décimales.
    Si bien que si tu écristu obtiens un résultat du genre 2,08 10^-17
    Une solution est de modifier ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ligne = 0
    Dim x As Double 
    For x = 1 To 2 Step 0.001
            If (Round(x * 1000, 6) = Int(Round(x * 1000, 6))) Then
                Cells(ligne, 1).Value = x
                ligne = ligne + 1
             End If
    Next
    J'ai pris 6 sans raison particulière.Ceci dit, ton exemple est tellement simplifié, qu'on ne voit plus l'intérêt du calcul, et, du coup, cela ne répond peut-être pas au besoin.

    Cordialement,

    PGZ

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut
    D'abord merci à tous pour vos réponses.
    Voici l'énoncé exact de mon problème : je connais 2 points (représentés par leurs coordonnées x et y) par lesquels passent un segment de droite. Je cherche tous les points de ce segment dont les coordonnées ont, au plus, 3 décimales.
    Voici donc l'ensemble de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    Dim x1 As Double
        Dim x2 As Double
        Dim y1 As Double
        Dim y2 As Double
     
        Dim a As Double
        Dim b As Double
     
        Dim x As Double
     
        x1 = 2559
        x2 = 2598
        y1 = 24127
        y2 = 24175
     
        'on calcule a et b tels que y = a*x + b
        a = (y1 - y2) / (x1 - x2)
        b = (x1 * y2 - x2 * y1) / (x1 - x2)
     
        Dim y As Double
     
        Dim ligne As Integer
        ligne = 5
        For x = x1 To x2 Step 0.001
            'je suis déjà obligée d'arrondir pour éviter un nombre important de décimales de type ,00000000033
            xArr = Round(x, 3)
            y = a * xArr + b
            If (y * 1000 = Val(Format(y * 1000, "#0"))) Then
                Cells(ligne, 1).Value = x
                Cells(ligne, 2).Value = y
                ligne = ligne + 1
            End If
        Next
    En utilisant la solution de babaothe, ça ne fonctionne pas tout le temps : exemple pour x=2570.427, on obtient y=24141.064 mais y * 1000 != Val(Format(y * 1000, "#0")) !!

    J'utilise donc la solution suggérée par pgz qui consiste à utiliser les valeurs arrondies.

    Je trouve quand même étonnant tant d'imprécision de la part d'un système (professionnel) de calcul...

  8. #8
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    324
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 324
    Par défaut
    Désolé, je n'ai pas le numéro de Bill Gates...
    De toutes les manières le code que j'ai donné n'est pas vraiment juste... Il faut mettre la différence en valeur absolue évidemment. Après c'est un problème d'arrondi avec Int qui donne 1000 au lieu de 1001!!! Il vaut mieux utiliser la fonction val à la place:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Dim x As Double, ligne As Integer
     
    ligne = 1
    For x = 1 To 2 Step 0.001
        If (Abs((x * 1000) - Val(x * 1000)) < 0.0001) Then
            Cells(ligne, 1).Value = x
            ligne = ligne + 1
         End If
    Next

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec fonctions et string/char
    Par vdumont dans le forum C++
    Réponses: 6
    Dernier message: 08/04/2006, 16h54
  2. Problème avec fonction
    Par Goundy dans le forum C
    Réponses: 24
    Dernier message: 01/10/2005, 20h17
  3. [MFC][WINSOCK] Problème avec fonction recv
    Par Le Farfadet dans le forum MFC
    Réponses: 4
    Dernier message: 23/09/2005, 11h00
  4. Problème avec fonction d'envoie de mail
    Par zyg dans le forum Réseau/Web
    Réponses: 1
    Dernier message: 23/02/2005, 08h48
  5. [Requête] Problème avec fonction "DATE_FORMAT()"
    Par sekiryou dans le forum Requêtes
    Réponses: 4
    Dernier message: 11/01/2005, 21h52

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