2017-10-17 10 views
-2

私はCでいくつかのビット操作をしようとしています。今まで私が行ったことはすべて正しいですが、最後のテストで間違いがあると言います。私にとっては関数はうまく見えますが...出力は期待したものとは異なります。ビット操作が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; 
} 

私のテストでは、次のようになります。私が得た

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(); 
    } 

出力は次のようになります。私は間違いですが、私は何も見えない場所を見つけるためにしようとしています

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

。たぶんあなたと女の子が見ることができますか?

+0

「PETER_xxx」は何ですか?これはテストプログラムの呼び出しにどのように関連していますか? – Barmar

+0

@Barmar離れることができます。私のモジュールの名前はそうです – gawron103

+1

ビット操作を扱うときには、一般に 'unsigned int'を使うべきです。 – Barmar

答えて

0

ビットツイリング機能はすべて、目的のビットを間違ってアドレス指定し、作業の最後に格納された値を破損しています。彼らはこの形を取る:

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

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

    *(storages[id]) = temp; 

は今tempの値のすべての操作が省略された場合でも、最終的な結果は、ほとんどの場合、格納された値に変更になることを確認します。

bitは、のuint8_tシーケンスで表されるビット配列のインデックスとみなされていると考えられます。その後、あなたの代わりに、その場合には、tempを初期化するからオブジェクトを指定する式はあなたがtempの最終的な値を記録したオブジェクトを指定の式と同じであるか、

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

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

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

ノートを書くかもしれません。

+0

おそらくあなたは正しいですが、残念ながらそのは私のために働いていない – gawron103

+1

@ gawron103私はあなたのコードを構築してテストしました。ジョン・ボリンジャーの修正プログラムが私のために働いています。なぜあなたがstoreageでその価値を取るのかはわかりません。このテストの場合は2であるので、tempは0になり、次にあなたまたはビット4で16に保存し、16/8を分割してtempを2に戻しますそれからあなたはビット4でORし、今は18です。あなたが望むものではありません。 – cleblanc

+0

ええ、機能の本体だけを変更しましたか? – gawron103

関連する問題