Précédent   Forum du club des développeurs et IT Pro > C et C++ > C
C Forum d'entraide technique sur le langage C. Avant de poster -> F.A.Q. C, Avant de poster.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 03/01/2013, 16h04   #1
Dev 37C
Invité de passage
 
Homme Florian Pasquereau
Conducteur de travaux
Inscription : décembre 2012
Messages : 9
Détails du profil
Informations personnelles :
Nom : Homme Florian Pasquereau
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Conducteur de travaux
Secteur : Bâtiment

Informations forums :
Inscription : décembre 2012
Messages : 9
Points : 2
Points : 2
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 :
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 :
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
Dev 37C est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/01/2013, 16h17   #2
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

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

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
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
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 03/01/2013, 17h00   #3
pfeuh
Membre Expert
 
Développeur en systèmes embarqués
Inscription : mars 2006
Messages : 763
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

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

Informations forums :
Inscription : mars 2006
Messages : 763
Points : 1 031
Points : 1 031
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 :
int getDigitValue(char digit, int base, int* result);
Je te le livre tel quel:

Code :
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;
}
pfeuh est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 03/01/2013, 17h41   #4
Dev 37C
Invité de passage
 
Homme Florian Pasquereau
Conducteur de travaux
Inscription : décembre 2012
Messages : 9
Détails du profil
Informations personnelles :
Nom : Homme Florian Pasquereau
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Conducteur de travaux
Secteur : Bâtiment

Informations forums :
Inscription : décembre 2012
Messages : 9
Points : 2
Points : 2
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 = ???
Dev 37C est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/01/2013, 19h31   #5
Kirilenko
Membre émérite
 
Avatar de Kirilenko
 
Homme Lucas Pesenti
Étudiant
Inscription : décembre 2011
Messages : 234
Détails du profil
Informations personnelles :
Nom : Homme Lucas Pesenti
Âge : 16
Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Étudiant
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : décembre 2011
Messages : 234
Points : 858
Points : 858
Envoyer un message via MSN à Kirilenko
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
Kirilenko est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 03/01/2013, 22h25   #6
Dev 37C
Invité de passage
 
Homme Florian Pasquereau
Conducteur de travaux
Inscription : décembre 2012
Messages : 9
Détails du profil
Informations personnelles :
Nom : Homme Florian Pasquereau
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Conducteur de travaux
Secteur : Bâtiment

Informations forums :
Inscription : décembre 2012
Messages : 9
Points : 2
Points : 2
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 :
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 .
Dev 37C est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 08h50.


 
 
 
 
Partenaires

Hébergement Web