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 :

Decalage bit a bit


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Pâtissier
    Inscrit en
    Avril 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Pâtissier

    Informations forums :
    Inscription : Avril 2014
    Messages : 32
    Par défaut Decalage bit a bit
    Bonjour, bonsoir.
    Pour comprendre et aprendre a utiliser les operateur bit a bit, je me suis amuser a afficher les variables en base 2.
    J ai commencer a bidouiller quelque decallage et sur un long (8 octect sur un x64) avec un decalage de 31,
    les 32 bit suivant sont initialiser a 1. Je ne comprend pas pourquoi est j aimerai savoir si quelqu un as une explication =)

    Voici mon code est l' exemple de la problematique :
    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
    #include <unistd.h>
     
    void	ft_putchar(char c)
    {
    	write(1, &c, 1);
    }
     
    void	ft_print_binary(void *data, size_t size)
    {
    	int		i;
     
    	i = 0;
     
    	while(size--)
    	{
    		i = 0;
    		while(i < 8)
    		{
    			if(*((char*)data + size)  & (128 >> i))
    				ft_putchar('1');
    			else
    				ft_putchar('0');
    			i++;
    		}
    		ft_putchar(' ');
    	}
    }
     
    int	main(void)
    {
    	long i;
    	ft_print_binary(&i, sizeof(i));
    	i = 1 << 31;
    	ft_putchar('\n');
    	ft_print_binary(&i, sizeof(i));
     
    }
    Resultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
    11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
    Un autre cas interessant un decalage superieure a 31m le compilateur
    m indique que mon decalage est impossible car je depasse la largeur du long.
    En resumer mon sizeof mindique bien 8 octect, je peux l initialiser qu dessus de l int max,
    mais aucun decalage au dessus de 32.

    Int max qui d ailleur est correctement innitialiser mais mal representer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    00000000 00000000 00000000 00000000 10000000 00000000 00000000 00001001 
    I = 2147483657%
    Voila merci d'avoir lu et ci vous avez une explication de la doc sa serai avec grand plaisir =)
    Desole pour l orthographe


    Je presice que pour sont utilisation que , j ai corriger le probleme grace a un unsigned long, ainsi qu un cast du decalage.
    De la maniere suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int     main(void)
    {
            unsigned long i;
            ft_print_binary(&i, sizeof(i));
            i = (unsigned)1 << 31;
            ft_putchar('\n');
            ft_print_binary(&i, sizeof(i));
     
    }
    Avec le resultat suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
    00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Par défaut, les constantes numériques entières sont interprétées comme des int (entiers signés de taille indéfinie).

    Lorsque tu écris : i = 1 << 31;, l'expression à droite du symbole d'affectation est évaluée d'abord, puis le résultat est affecté à la variable i. Peu importe le type de i ici, 1 et 31 sont des int ce qui définira également le type de l'expression.

    Pour que l'opération s'effectue de la manière recherchée, tu dois explicitement caster chaque paramètre de l'expression vers le type de i (ou utiliser un suffixe litéral).

    Lorsque tu fais ce genre de manipulation où la taille des entiers compte, ne te base pas sur des suppositions et utilise les types fixés : http://en.cppreference.com/w/c/types/integer .

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Et l'entier 1 << 31 est en réalité négatif, il vaut -2147483648.
    La conversion d'un entier-32bits en long-64bits va conserver le signe d'où la série de 1 dans le long.
    En écrivant i = 1L << 31 on aura directement un calcul long et seul le bit31 sera positionné.

  4. #4
    Membre Expert
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Par défaut
    Bonjour,
    pour compléter un peu les réponses, il vaut mieux, quand on essaye de manipuler la représentation des entiers bit à bit de n'utiliser que des types non signés.
    Utiliser les types classiques en supposant quoi que ce soit sur leur longueur en bit ou sur leur signedness est également risqué. Par exemple, tu pars du principe qu'un long fait 64 bits sur une architecture 64 bits. C'est une hypothèse fausse si tu utilises windows par exemple, car dans ce cas un long ne fera que 32 bits, même en compilant en 64 bits pour du windows 64 bits, en revanche cette hypothèse est vraie si tu compiles en 64 bits sur d'autres plateformes 64 bits comme linux, mac, *bsd, …
    Utiliser le type char est risqué aussi car c'est un type différent de signed char (seul cas ou un type de base est différent s'il est préfixé par signed) et de unsigned char. A priori tu ne peux pas supposer qu'il est signé (ou pas). Tu ne peux pas non plus supposer qu'un char fait 8 bits.
    Du coup, si tu veux manipuler les bits en utilisant un type ayant non seulement une taille connue et fixe et étant non signé il faut absolument te tourner vers les types définis dans stdint.h/inttypes.h. Tu as, entre autre, à ta disposition les types intN_t et uintN_t avec N=8,16,32,64 qui sont respectivement des types entier signé codé en complément à 2/non signé de taille 8,16,32,64 bits.
    Cela est vrai sur les plateformes classiques modernes.
    Tu devrais utiliser des uint8_t pour être certain de manipuler un octet non signé, et des uint64_t pour être certain de manipuler des entiers de 64 bits non signés.

  5. #5
    Membre averti
    Homme Profil pro
    Pâtissier
    Inscrit en
    Avril 2014
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Pâtissier

    Informations forums :
    Inscription : Avril 2014
    Messages : 32
    Par défaut
    Merci de c 'est explication =)

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

Discussions similaires

  1. Decalage de 8 bit
    Par passicon dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 09/10/2007, 17h46
  2. Comment lire un char bit a bit ?
    Par damien99 dans le forum C++
    Réponses: 9
    Dernier message: 02/02/2006, 21h57
  3. Lire bit par bit
    Par The_Undertaker dans le forum C++
    Réponses: 8
    Dernier message: 01/07/2005, 11h43
  4. Conversion de handles 16 bits <--> 32 bits
    Par Alcatîz dans le forum Windows
    Réponses: 6
    Dernier message: 13/12/2003, 13h40
  5. Désassemblage à la main 16 bits / 32 bits
    Par le mage tophinus dans le forum Assembleur
    Réponses: 12
    Dernier message: 19/04/2003, 00h55

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