2017-10-17 19 views
-2

J'essaie de faire quelques opérations de bits dans C. Jusqu'à présent tout ce que j'ai fait est correct mais à la fin des tests dit qu'il y a une erreur. Pour moi, la fonction semble bien, mais ... la sortie est différente que prévu.Les opérations de bits ont mal tourné dans C

#include <stdint.h> 

#include "PETER_interface.h" 

const int BITS_IN_BYTE = 8; 
static int g_capacity = 0; 
static int g_size = 0; 
static container_id_t indexOfTable = 0; 

uint8_t* storages[4] = {0 ,0 ,0 ,0}; 

err_t PETER_new(container_id_t* id, int num_of_bits) { 
    storages[indexOfTable] = (uint8_t*)(malloc((num_of_bits/BITS_IN_BYTE) 
    + (num_of_bits % BITS_IN_BYTE) ? 1 : 0)); 

    g_capacity = num_of_bits; 
    g_size = ((num_of_bits/BITS_IN_BYTE) + (num_of_bits % BITS_IN_BYTE) ? 
1 : 0); 

    *id = indexOfTable; 

    indexOfTable++; 

    return E_OK; 
} 

err_t PETER_resize(container_id_t id, int bit) { 
    return E_NOT_IMPLEMENTED; 
} 

err_t PETER_delete(container_id_t id) { 
    return E_NOT_IMPLEMENTED; 
} 

err_t PETER_deleteAll() { 
    return E_NOT_IMPLEMENTED; 
} 

err_t PETER_set(container_id_t id, int bit) { 
    uint8_t temp = *(storages[id])/BITS_IN_BYTE; 

    temp |= (1 << (bit % BITS_IN_BYTE)); 

    *(storages[id]) = temp; 

    return E_OK; 
} 

err_t PETER_clear(container_id_t id, int bit) { 
    uint8_t temp = *(storages[id])/BITS_IN_BYTE; 

    temp &= ~(1 << (bit % BITS_IN_BYTE)); 

    *(storages[id]) = temp; 

    return E_OK; 
} 

err_t PETER_invert(container_id_t id, int bit) {  
    uint8_t temp = *(storages[id])/BITS_IN_BYTE; 

    temp ^= (1 << (bit % BITS_IN_BYTE)); 

    *(storages[id]) = temp; 

    return E_OK; 
} 

err_t PETER_capacity(container_id_t id, int *capacity) { 
    *capacity = g_capacity; 

    return E_OK; 
} 

err_t PETER_storageSize(container_id_t id, int *size) { 
    *size = g_size; 

    return E_OK; 
} 

err_t PETER_get(container_id_t id, int flag_no, int *return_value) {  
    *return_value = (*(storages[id]) >> (flag_no % BITS_IN_BYTE)) & 1; 

    return E_OK; 
} 

Mes tests ressemble à ceci:

int ok = 1; 

    const int size = 8; 
    container_id_t id; 
    int val; 


    OK( new(&id,size),   E_OK ); 

    OK( capacity(id, &val), E_OK ); 
    OK( val, size); 

    OK( storageSize(id, &val), E_OK ); 
    OK( val, 1); 

    printf("storageSize: %d\n", val); 

    OK( set(id, 4),   E_OK ); 
    OK( get(id, 4, &val),  E_OK ); 

    printf("set: %d\n", val); 

    OK( val, 1); 

    OK( clear(id, 4),   E_OK ); 
    OK( get(id, 4, &val),  E_OK ); 

    printf("clear: %d\n", val); 

    OK( val, 0); 

    OK( invert(id, 4),   E_OK );  
    OK( get(id, 4, &val),  E_OK ); 

    printf("invert: %d\n", val); 

    OK( val, 1); 

    OK( invert(id, 4),   E_OK ); 
    OK( get(id, 4, &val),  E_OK ); 

    printf("invert: %d\n", val); 

    OK( val, 0); 


    // not yet implemented 
    OK( resize(id, 2*size),E_NOT_IMPLEMENTED ); 
    OK( delete(id),  E_NOT_IMPLEMENTED ); 
    OK( deleteAll(),  E_NOT_IMPLEMENTED ); 



    if(ok == 1) { 
     OUT_GREEN(); 
     printf("%s: ok", module_name); 
     OUT_WHITE(); 
    } 

sortie que je suis arrivé ressemble à ceci:

Run tests 
storageSize: 1 
set: 1 
clear: 0 
invert: 1 
invert: 1 
fail line 84 (which is second invert) 

Je suis en train de trouver où est l'erreur, mais je ne vois rien. Peut-être que vous les gars et les filles pouvez voir?

+0

Qu'est-ce que tout le contenu de 'PETER_xxx'? Comment cela est-il lié aux appels dans le programme de test? – Barmar

+0

@Barmar Vous pouvez le quitter. C'est le nom de mon module – gawron103

+1

Vous devriez généralement utiliser 'unsigned int' pour les opérations sur les bits. – Barmar

Répondre

0

Toutes vos fonctions de modification de bit adressent le bit souhaité à tort et corrompent les valeurs stockées à la fin de leur travail. Ils prennent cette forme:

uint8_t temp = *(storages[id])/BITS_IN_BYTE; 

    // ... perform some operation on temp ... 

    *(storages[id]) = temp; 

Observons maintenant que même si toutes les manipulations de la valeur de temp ont été omis, le résultat final serait, dans la plupart des cas, un changement à la valeur mémorisée.

Je suppose que le paramètre bit est censé être pris comme un index dans un tableau de bits représenté par la séquence uint8_t à storages[i]. Ensuite, vous pourriez écrire au lieu

uint8_t temp = (storages[id])[bit/BITS_IN_BYTE]; 

    // ... perform some operation on temp ... 

    (storages[id])[bit/BITS_IN_BYTE] = temp; 

Notez comment, dans ce cas, l'expression désignant l'objet à partir de laquelle initialiser temp est le même que l'expression désignant l'objet dans lequel vous enregistrez temp valeur finale de l ».

+0

probablement vous avez raison, mais malheureusement sa ne fonctionne pas pour moi – gawron103

+1

. @ gawron103 J'ai construit et testé votre code et le correctif de John Bollinger fonctionne pour moi, cela n'a pas de sens pour moi pourquoi vous prendriez la valeur à storeage s [i] et diviser par 8. Dans le cas de ce test c'est 2 donc temp devient 0, alors vous ou dans le bit 4 et enregistrez-le comme 16, puis quand vous le retirez, vous divisez 16/8 et temp est 2 , alors vous OU dans le bit 4 encore et c'est maintenant 18. Pas ce que vous voulez. – cleblanc

+0

Hmmm ok, mais vous avez seulement changé les fonctions des corps? – gawron103