2012-03-03 4 views
0

を含ま私は2つの配列を1つは符号なしの文字で、もう1つは符号なしの整数で作成します。考えられるのはrgba配列をシミュレートし、それをポインタまたはビットごとに操作することの違いです。は、ビット単位の操作配列から誤った値を受け、Cのコードは、私はビット単位の詳細については、私はそれで私のコードのパフォーマンスを向上する方法を見しようとしているので、私はそのコードでは、テストコードを作った

すべてが機能していることを確認するには、最後に配列のすべての値の合計を計算します。問題は、ポインタで操作した配列の値がビット単位の値と異なる点です。整数配列には4つの位置しかなく、char配列には16があります。彼らは私に最終的に同じ結果を与えるべきですが、char 1だけが私にそれを与えます(2000年は償いの結果です)。ここで

はコードです:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 

inline double 
ucharArray(void); 

inline double 
intArray(void); 

int32_t 
main(int32_t argc, int8_t* argv[]) 
{ 
    double sum = 0; 

    sum = ucharArray(); 

    printf("%lf\n", sum); 

    sum = 0; 

    sum = intArray(); 

    printf("%lf\n", sum); 

    return 0; 
} 

inline double 
intArray(void) 
{ 
    double sum = 0; 
    uint32_t* array_uint = (uint32_t*) malloc(2 * 2 * sizeof(uint32_t)); 

    register uint32_t* p_a = array_uint; 
    register uint32_t* p_last = p_a + 2 * 2; 

    for (;;) 
    { 
    *p_a |= (50 << 24); 
    *p_a |= (100 << 16); 
    *p_a |= (150 << 8); 
    *p_a |= 200; 

    if (p_a == p_last) 
     break; 
    p_a++; 
    } 

    p_a = array_uint; 
    for (;;) 
    { 
    sum += (*p_a & 0xFF000000) >> 24; 
    sum += (*p_a & 0x00FF0000) >> 16; 
    sum += (*p_a & 0x0000FF00) >> 8; 
    sum += *p_a & 0x000000FF; 

    if (p_a == p_last) 
     break; 
    p_a++; 
    } 

    free(array_uint); 

    return sum; 
} 

inline double 
ucharArray(void) 
{ 
    double sum = 0; 
    uint8_t* array_uchar = (uint8_t*) malloc(2 * 2 * 4 * sizeof(uint8_t)); 

    register uint8_t* p_a = array_uchar; 
    register uint8_t* p_last = p_a + 2 * 2 * 4; 

    for (;;) 
    { 
    *p_a = 50; 
    p_a++; 
    *p_a = 100; 
    p_a++; 
    *p_a = 150; 
    p_a++; 
    *p_a = 200; 
    p_a++; 

    if (p_a == p_last) 
     break; 
    } 

    p_a = array_uchar; 
    for (;;) 
    { 
    sum += *p_a; 
    p_a++; 
    sum += *p_a; 
    p_a++; 
    sum += *p_a; 
    p_a++; 
    sum += *p_a; 
    p_a++; 

    if (p_a == p_last) 
     break; 
    } 

    free(array_uchar); 

    return sum; 
} 

そして相続人は私の出力です:

~ $ gcc test.c -g 
~ $ ./a.out 
2000.000000 
3484.000000 
+1

あまりにも多くのSOの質問のコード。あなたの例を問題/矛盾がまだ残っている最小限に抑えてください。 –

答えて

1

1つの問題は、あなたがあなたのint型のバイトにビット単位の論理和値をしているということですが、あなたは最初にそれをゼロにしていない - これはあなたが意図的に含めている値の論理和の組み合わせを取得していること、および既にそこに(ランダムに)何があったのか。だから、これを変更:

*p_a |= (50 << 24); 
*p_a |= (100 << 16); 
*p_a |= (150 << 8); 
*p_a |= 200; 

...これに:

*p_a = (50 << 24) | (100 << 16) | (150 << 8) | 200; 

...または単に最初のゼロに*p_aを設定します。

ただし、コードではビッグエンディアンシステムも想定されています。

*p_a = 50 | (100 << 8) | (150 << 16) | (200 << 24); 

...あなたがucharArray()バージョンで何を一致させるために:あなたは、x86のようなリトルエンディアンのシステムにしている場合は、値の位置を逆にする必要があります。


@Christian Ammerも右のようである:

p_a++; 
if (p_a == p_last) 
    break; 

...テストは、インクリメント後に来るように:

if (p_a == p_last) 
    break; 
p_a++; 

...する必要があります。 (あなたのintバージョンの2つの場所で)

+0

ドミトリーに感謝します。本当に問題でした。 – Sassa

1

二点があります:あなたが前にポインタをインクリメントする必要がintArray

  1. は、ループ終了条件(2回)

    p_a++; // here 
    if (p_a == p_last) 
        break; 
    
    それ以外の場合、ループは頻繁に1回繰り返します割り当てられていないメモリを上書きします。

  2. あなたは、配列array_uintを初期化する必要があります。

この修正後、私は両方のバージョンで2000.0を得ました。

+0

あなたは正しいです、intArrayはこの間違ったインクリメントのためもう一度繰り返していました。ありがとう! – Sassa

関連する問題