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

 C Discussion :

obtenir le n-ième élément d'un nombre!


Sujet :

C

  1. #1
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 52
    Par défaut obtenir le n-ième élément d'un nombre!
    Bonjour!

    Je suis confronté à un problème relativement idiot, mais je ne comprends pas pourquoi ca ne fonctionne pas!

    Je cherche à obtenir un certain élément d'un nombre. Par exemple, je cherche à obtenir le 3ème élément de 3215, et j'obtiendrai 2.

    J'ai écrit la fonction suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int get(int number, int element)
    {
        return (number / ((int) pow(10,element))) % 10;
    }

    Elle fonctionne parfaitement, sauf dans certains cas où elle bug complétement, sans que je sache pourquoi.

    Par exemple:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    int get(int number, int element)
    {
        return (number / ((int) pow(10,element))) % 10;
    }
     
     
    int main(void)
    {
        printf("%d ", get(3125, 2));
        printf("%d ", get(3125, 1));
        printf("%d ", get(3125, 4));
        printf("%d ", get(0, 0));
        printf("%d ", get(3005, 2));
        printf("%d ", get(3005, 0));
     
        return 0;
    }
    donnera:

    1 2 0 0 0 5
    Mais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d ", get(12034, 2));
    donnera:
    1
    D'où peut venir le problème?

    Je ne comprends vraiment pas :/

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Mais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d ", get(12034, 2));
    donnera:
    1
    D'où peut venir le problème?
    Bizarre. Chez moi, ton code donne 0 !

  3. #3
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 52
    Par défaut
    J'ai réussir à obtenir une réponse vraiment étrange sur un autre forum qui est d'utiliser la fonction floor() avant de caster pow en int. Ce qui donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int get(int number, int element)
    {
        return number / (int)floor(pow(10, element)) % 10;
    }
    C'est vriament bizarre là parce que ca fonctionne pour certains résultats et pas pour d'autres... Et sur certains ordinateurs ca fonctionne...

    Ca arrive souvent ce genre de choses étranges?

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    je pense que le problème vient de la fonction pow qui n'est pas bien adaptée au calcul des entiers : Normalement, on attend que pow(10, 2) donne 100.000000... dont la partie entière est 100. Mais, une implémentation peut fournir comme résultat 99.9999999.... dont la partie entière est 99.
    Dans ce cas, 12034/99 donnera 121.5556 (et non pas 120.34 attendu), d'où le résultat observé.

    Pour éviter cela, faire le calcul en entier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int get(int number, int element)
    {
      int i; 
      int fact = 1;
      for(i=0;i<element;i++) fact *= 10;    
      return number / fact % 10;
    }
    Ce code est certainement plus rapide en exécution que l'utilisation de pow() qui est une fonction "compliquée", conçue pour calculer x^^y avec x et y des doubles et pas forcément optimisée pour y entier.

    Si tu tiens à utiliser pow(), force l'arrondi au lieu de laisser la troncature pure et dure en faisant, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     return number / (int)(pow(10, element)+0.1) % 10;
    Je ne pense pas que l'utilisation de floor() change les choses.

  5. #5
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Si je puis me permettre, tu y gagnes un tout petit peu avec cette version :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int get ( int number, int element )
        {
        for (; element > 0 ; element-- ) number /= 10 ;    
        return number % 10;
        }
    Mais évite les pow, floor et autres fonctions spécifiques aux flottants : il y a souvent des problèmes d'arrondi inattendus que tu es obligé de gérer.
    En plus, au niveau perf c'est affreux !
    Enfin, ça alourdi ton exécutable car il va devoir embarquer des bouts de la librairie de math.

    D'une manière générale, évite les nombres flottants tant que tu n'en as pas un réel besoin.

  6. #6
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    Je trouve également que si on peut éviter les flottants, il ne faut pas se gêner. Pour la lisibilité, j'aurais fait ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int get(int number, int index)
    {
        while(index)
        {
            number /= 10;
            index--;
        }
        return number % 10;
    }

Discussions similaires

  1. Obtenir valeur d'un élément fils dans form
    Par shadowbob dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 03/06/2008, 17h03
  2. Accès à k ième élément d'un GtkComboBox
    Par KiKiTiTi dans le forum GTK+ avec C & C++
    Réponses: 4
    Dernier message: 28/03/2008, 18h21
  3. Réponses: 3
    Dernier message: 17/08/2007, 16h17
  4. [XI] comment obtenir uniquement la valeur entiere d'un nombre ?
    Par c_moi_c_moi dans le forum SAP Crystal Reports
    Réponses: 12
    Dernier message: 18/06/2007, 14h04
  5. [68000] Accéder au ième élément d'un tableau
    Par topmas dans le forum Autres architectures
    Réponses: 1
    Dernier message: 23/04/2007, 21h26

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