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 :

Conversion nombre décimal négatif


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut Conversion nombre décimal négatif
    Bonjour à tous je suis en train de coder une fonction qui retourne une chaine de caractère en fonction d'un int passé en paramètres et de la base souhaitée.

    Voici le prototype
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int
    intStr(char s[],const int tailletab,const int n, const int b)
    Ma fonction fonctionne très bien pour les nombres positif, mon problème est pour les nombres négatif autre décimal, je ne trouves pas sur internet une méthode pour faire cette conversion Si l'un d'entre vous a un lien ou quelque chose, je suis preneur. merci

    Voici ma fonction

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    int
    intStr(char s[],const int tailletab,const int n, const int b)
    //convertit n en un string en fonction de la base (b)
    {
        int i = 0, signe = n, iMax = 1, chifre;
     
    //partie binaire décimal et hexadécimal
        if(b == 2 || b == 10 || b == 16)
        {
            if(n < 0) // rend le nombre positif si il est négatif
            {
                signe = - signe;
                if(b == 10)
                    iMax = 2;
            }
     
            do
            /*copie dans le tableau en a l'envers
              Exemple: si le nombre est -123 le tableau sera 321-.*/
            {
                chifre = signe % b;
     
                if(chifre > 9)
                {
                    switch(chifre)
                    {
                        case(10): s[i++] = 'A'; break;
                        case(11): s[i++] = 'B'; break;
                        case(12): s[i++] = 'C'; break;
                        case(13): s[i++] = 'D'; break;
                        case(14): s[i++] = 'E'; break;
                        case(15): s[i++] = 'F'; break;
                    }
                }
                else
                    s[i++] = chifre + '0';
            }
            while((signe /= b) > 0 && i < tailletab - iMax);
     
            if(i >= tailletab - iMax && signe != 0)// si le tableau est trop petit
                return 0;
     
    //gere les nombres négatif
            if(n < 0 && b == 10)
                s[i++] = '-';
            else if(n < 0 && b == 2)
                while((!(i > 32)) && i < (tailletab /4) * 4)
                    s[i++] = '1';
            else if(n < 0 && b == 16)
                while((!(i > 8)) && i < tailletab -2)
                    s[i++] = 'F';
     
            s[i] = '\0';// signe de fin de chaine
     
            inverser(s);
     
            return 1;
        }
        else
            return 0;
    }
    Je suis amateur en programmation donc pas trop de mots technique svp si vous remarquez des erreurs

    Merci

  2. #2
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    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 : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Citation Envoyé par Dev 37C Voir le message
    mon problème est pour les nombres négatif, je ne trouves pas sur internet une méthode pour faire cette conversion
    Je vais essayer de ne pas être technique. La valeur absolue d'un entier négatif, c'est son complément à 2 augmenté de 1. Si on parle de 8 bits, -1 est codé 0xff ou 0b11111111, le complément à 2 est obtenu par l'inversion de tous les bits, ce qui donne 0x00 ou 0b0000000. on augmente de 1 ce qui donne 0x01 ou 0b00000001 et est bien la valeur absolue de -1.

    En logique pure un entier est négatif si son bit de poids le plus élevé est à 1.

    A+

    Pfeuh

  3. #3
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    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 : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Je viens de retrouver un de mes vieux snippets, qui ne gère pas les erreurs. C'est normal, si tu retournes un int, il n'y a pas de code d'erreur possible, il faudrait un prototype dont un des paramètres serait un pointeur vers le résultat et qui retournerait success ou failure, comme par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int getDigitValue(char digit, int base, int* result);
    Je te le livre tel quel:

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
     
    int getDigitValue(char digit, int base)
    {
        int digit_value;
        switch(digit)
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                digit_value = digit - '0';
                break;
            case 'a':
            case 'b':
            case 'c':
            case 'd':
            case 'e':
            case 'f':
                digit_value = digit - 'a' + 10;
                break;
            case 'A':
            case 'B':
            case 'C':
            case 'D':
            case 'E':
            case 'F':
                digit_value = digit - 'A' + 10;
                break;
            default:
                digit_value = -1; /* Error not numerical digit */
                break;
        }
        if(digit_value >= base)
            digit_value = -1; /* Error digit out of range */
        return digit_value;
    }
     
    int getIntFromBase(char* text, int base)
    {
        int index = 0;
        int value = 0;
        int negative = 0;
        char digit;
        int digit_value;
     
        if (text[0] == '\0')
            return value; /* error empty string */
        if (text[0] == '-')
        {
            negative = 1;
            index = 1;
        }
        else
        if (text[0] == '+')
        {
            index = 1;
        }
        while(index != 31)
        {
            digit = text[index++];
            if(digit == '\0')
                break;
            digit_value = getDigitValue(digit, base);
            if(digit_value < 0)
                break; /* error, bad input character */
            value = value * base + digit_value;
        }
        if(negative != 0)
            value = (value ^ 0xffffffff) + 1;
        return value;
    }
     
    int main(void)
    {
        printf("%i\n", getIntFromBase("-123", 16));
        assert(getDigitValue('8', 8) == -1);
        assert(getDigitValue('8', 9) == 8);
        assert(getIntFromBase("fF", 16) == 255);
        assert(getIntFromBase("+fF", 16) == 255);
        assert(getIntFromBase("-fF", 16) == -255);
        assert(getIntFromBase("777", 8) == 511);
        printf("A L L   T E S T S   P A S S E D !\n");
        return 0;
    }

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut
    Ok donc si j'ai bien compris

    123 = 1111011
    - 123 = 0000101

    c'est bien ça ?

    Par contre je ne comprends pas pour les hexa.....
    123 = 7B
    -123 = ???

  5. #5
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    Salut,

    En fait, il n'y a pas de représentation « universelle » d'un nombre négatif (typiquement, le langage C lui-même autorise trois représentations différentes : signe et magnitude, complément à 1 et complément à 2). Cependant, celle qui est majoritairement utilisée dans les systèmes informatisés actuels, c'est le complément à 2. Elle consiste à prendre le complément à 1 d'un nombre (c'est-à-dire l'inverse de tous ses bits) et à ajouter 1.

    Sur 8 bits, on a 123 qui vaut 0x7b (0b01111011) et -123 qui vaut 0x85 (0b10000101).
    Sur 32 bits, on a 123 qui vaut 0x0000007b (0b00000000000000000000000001111011) et -123 qui vaut 0xffffff85 (0b11111111111111111111111110000101).

    Bonne soirée.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut
    Voici la version finale. Je pense qu'il est possible de l'optimiser au niveau des switch.

    Merci aux personnes qui mon aidé. C'est vraiment cool, ce sera un peu grasse a vous si je suis bon un jour

    Voici le 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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    int
    intStr(char s[],const int tailletab,const int n, const int b)
    //convertit n en un string en fonction de la base (b)
    {
        int i = 0, signe = n, chiffre, memI, octe = ((tailletab-1) /4) * 4, pDernier1;
     
    //gère le nombre à afficher dans le tableau
        if(tailletab > 64 && octe >= 64 && (b == 2 || b == 16))
            octe = 64;
        else if(tailletab > 32 && octe >= 32 && (b == 2 || b == 16))
            octe = 32;
        else if(tailletab > 16 && octe >= 16 && (b == 2 || b == 16))
            octe = 16;
        else if(tailletab > 8 && octe >= 8 && (b == 2 || b == 16))
            octe = 8;
        else
            octe = 4;
     
       if(b == 16)
            octe = octe / 4;
     
    // Rend le nombre positif si il est négatif
        if(b == 2 || b == 10 || b == 16)
        {
            if(n < 0)
                signe = - signe;
     
    /*copie dans le tableau en à l’envers.
      Exemple:
              Si le nombre est -123 le tableau sera 321-.*/
            do
                if((chiffre = signe % b) > 9)
                    s[i++] = chiffre - 10 + 'A';
                else
                    s[i++] = chiffre + '0';
            while((signe /= b) > 0 && i < octe);
     
            if(i >= octe && signe != 0)// si le tableau est trop petit quite la fonction
                return 0;
     
            while(i < octe && (b == 2 ||b == 16))// rajout des 0 pour compléter
                    s[i++] = '0';
     
    //gère les nombres négatif
        //decimal
            if(n < 0 && b == 10)
                s[i++] = '-';
        //hexadecimal et binaire
            else if(n < 0)
            {
                for(memI = i; memI >= 0; memI --)
                //inverse tous les nombres
                    if(b == 16)
                        switch(s[memI])
                        {
                            case '0': s[memI] = 'F'; break;
                            case '1': s[memI] = 'E'; pDernier1 = memI; break;
                            case '2': s[memI] = 'D'; pDernier1 = memI; break;
                            case '3': s[memI] = 'C'; pDernier1 = memI; break;
                            case '4': s[memI] = 'B'; pDernier1 = memI; break;
                            case '5': s[memI] = 'a'; pDernier1 = memI; break;
                            case '6': s[memI] = '9'; pDernier1 = memI; break;
                            case '7': s[memI] = '8'; pDernier1 = memI; break;
                            case '8': s[memI] = '7'; pDernier1 = memI; break;
                            case '9': s[memI] = '6'; pDernier1 = memI; break;
                            case 'A': s[memI] = '5'; pDernier1 = memI; break;
                            case 'B': s[memI] = '4'; pDernier1 = memI; break;
                            case 'C': s[memI] = '3'; pDernier1 = memI; break;
                            case 'D': s[memI] = '2'; pDernier1 = memI; break;
                            case 'E': s[memI] = '1'; pDernier1 = memI; break;
                            case 'F': s[memI] = '0'; pDernier1 = memI; break;
                        }
                    else
                        if(s[memI] == '1')
                        {
                            s[memI] = '0';
                            pDernier1 = memI;//memorise la place du bit a 1
                        }
                        else
                            s[memI] = '1';
     
                s[pDernier1] = (b == 2)? '1': s[pDernier1] +1 ;
                for(pDernier1 --;pDernier1 >= 0; pDernier1 --)
                //met tous les bits de gauche (gauche car le tableau est inversé) du bit 1 a 0
                    s[pDernier1] = '0';
            }
     
            s[i] = '\0';// signe de fin de chaine
     
            inverser(s);
     
            return 1;
        }
        else
            return 0;
    }
    Si vous voyez des erreurs Faites-moi signe

    Bonne année à tous, et encore merci .

Discussions similaires

  1. [XL-2003] Conversion nombre décimal en heure
    Par anonymous1.0 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 03/02/2011, 12h54
  2. Conversion nombre décimal <-> binaire (signé et flottant)
    Par lecteur1001 dans le forum Simulink
    Réponses: 12
    Dernier message: 06/01/2011, 16h49
  3. Conversion nombre décimal en virgule flottante IEEE 754 (exprimé en hexa)
    Par vinssieux dans le forum Macros et VBA Excel
    Réponses: 36
    Dernier message: 15/05/2008, 09h40
  4. Réponses: 3
    Dernier message: 21/12/2007, 15h13

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