一個簡單的面試題目-竟然花了半天時間


一個簡單的面試題目-竟然花了半天時間才調試通。一方面是因為水平有限,另一方面就是對移位運算不是非常的了解。如果你也不是很了解移位運算,這是一個很好的學習的機會。

面試題

參考:http://topic.csdn.net/u/20080823/00/f2597efb-f00d-4ec6-9c6e-ecfe3f003f59.html

6. You have an array of 4 32-bit integers which you use to store a 128-bit number. Fill in the following functions for bitwise shifting operations.

uint32 storage[4];  (大致的意思是:對一個數組移位運算

一個簡潔但是錯誤的答案(至少有一點,當count>32時就有問題了

void ShiftLeft(int count)
{
    unsigned int temp = 0;
    for(int i = 0; i < 4; ++i)
    {
        storage[i] = storage[i] << count | temp;
        temp = storage[i] >> sizeof(unsigned int)*8 - count;
    }
}
bool ShiftRight(int count)
{
    unsigned int temp = 0;
    for(int i = 3; i >= 0; --i)
    {
        storage[i] = storage[i] >> count | temp;
        temp = storage[i] << sizeof(unsigned int)*8 - count;
    }
}

我的實現如下所示。默認使用小端序,這樣便於處理,還有就是print的時候先輸出低位,后輸出高位。

雖然沒有通過完全的測試,但是程序的邏輯應該沒有問題的。

考慮到復用和可讀性,這里使用了大量的,如果你有什么更好的建議,希望你能告訴我。

#include <stdio.h>

typedef unsigned int u32;

//               0     1      2      3
// 假設使用小端序0-31, 32-63, 64-95, 96-127
#define N 4
u32 data[N] = { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 };

#define bit_get(num, i) ( ((num) >> i) & 1 )
#define bit_set1(num, i) do { num |= (1 << (i)); } while(0)
#define bit_set0(num, i) do { num &= ( ~(1 << (i)) ); } while(0)
#define data_bit(i) ( bit_get(data[(i) / 32], (i) % 32) )
#define data_set1(i) bit_set1(data[(i) / 32], (i) % 32)
#define data_set0(i) bit_set0(data[(i) / 32], (i) % 32)

#define bit_low(n) (u32)( (1 << (n)) -1 )
#define bit_high(n) (u32)( bit_low(n) << (32 - (n)) )
#define shift_left(num, n) ( (num) << (n) )
#define shift_right(num, n) ( (num) >> (n) )
#define shift_left_out(num, n) ( (num) & bit_low(n) )
#define shift_right_out(num, n) ( (num) & bit_high(n) )
#define pad_low(out, n) ( (out) << (32 - (n)) )
#define pad_high(out, n) ( (out) >> (32 - (n)) )

#define u32_bits() (sizeof(u32) * 8)

void data_not() {
	u32 i, len = 32 * N;
	for(i=0;i<len;i++) {
		if(data_bit(i) == 0) { 
			data_set1(i); 
		} else { 
			data_set0(i);
		}
	}
}

void data_shift_left(int n) {
	u32 i,j;
	for(j=0;j<n;j++) {
		for(i=1;i<N-j;i++) {
			data[i-1] = data[i];
		}
		data[N-1-j] = 0;
	}
}

void data_shift_right(int n) {
	u32 i,j;
	for(j=0;j<n;j++) {
		for(i=N-1;i>j;i--) {
			data[i] = data[i-1];
		}
		data[j] = 0;
	}
}

u32 data_bit_shift_left(int n) {
	int i;
	u32 div = n / u32_bits(), out, last_out = 0;
	n %= u32_bits();
	if(div > 0) {
		data_shift_left(div);
		return data_bit_shift_left(n);
	} else {
		for(i = N-1; i >= 0; i--) {
			out = shift_left_out(data[i], n);
			data[i] = (data[i] >> n) | pad_low(last_out, n);
			last_out = out;
		}
	}
	return last_out;
}

u32 data_bit_shift_right(int n) {
	int i;
	u32 div = n / u32_bits(), out, last_out = 0;
	n %= u32_bits();
	if(div > 0) {
		data_shift_right(div);
		return data_bit_shift_right(n);
	} else {
		for(i = 0; i < N; i++) {
			out = shift_right_out(data[i], n);
			data[i] = (data[i] << n) | pad_high(last_out, n);
			last_out = out;
		}
	}
	return last_out;
}

void data_bit_print() {
	int i;
	u32 len = u32_bits() * N;
	for(i=0;i<len;i++) {
		if(i % u32_bits() == 0) { printf("\n"); }
		printf("%d", data_bit(i));
	}
	printf("\n");
}

int main(int argc, char *argv[]) {
	data_bit_print();
	data_bit_shift_left(120);
	data_bit_print();

	return 0;
}

移位運算的總結

1、在C/C++中對負數與或非,移位運算會出現什么結果呢?比如:(-2) & 65535 = ?

通過GCC編譯發現結果為0xfffe,可能是因為0xfffe & 0xffff = 0xfffe,其實,這里我還有一個疑問:這里的類型是如何來轉換的,-2如果轉換為int32類型就不是這樣的結果了。

2、如果來獲取比特位,或者設置比特位的值。使用上面的幾個宏(bit_get,bit_set0,bit_set1)可以很好的實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM