PDA

View Full Version : Chuyển 16bit sang 24bit



phamtrungthanh
10-03-2010, 16:19
Mình có môt bài toán như sau
Mình có một kiểu dữ liệu 16bit làm cách nào để chuyển sang 24bit
vd: 5 6 5
input: 11111 111111 11111
8 8 8
output: 00011111 00111111 00011111
dùng c/c++, gợi ý chủ yếu sử dụng ép kiểu... (chưa bít làm sao hic hic)
void convertto24bit(void *input, void *output){
//code
}
// input, output là kiểu dữ liệu tùy chọn (int, long, ...)

tinhanh909
10-03-2010, 16:26
bạn nào có chương trinh ghi phim lại như của nhất nghệ không?cho share cho mình với!thank!

scooby
11-03-2010, 07:22
C/C++ làm gì có kiểu dữ liệu nào 24 bit?

phamtrungthanh
11-03-2010, 16:52
đây là một bài test của gameloft, bữa mình phỏng vấn
và đây là bài làm của mình các bạn tham khảo cho ý kiến
Còn một cách nữa là dùng mặt lạ(ở đây mình chỉ dịch bít thôi)
mình dùng kiểu int (4byte)
void cv16to32(unsigned void *in, unsigned void *out){
unsigned int tmp = *in;
// Lấy 5bit cuối cùng
*in = *in<<27;
*in = *in>>27;
*out = *in;// Gán giá trị cho con trỏ out
// Lấy 6 bít ở giữa
*in = tmp;
*in = *in>>5;
*in = *in<<26;
*in = *in>>18;
*out += *in;
// Lấy 5bit ở đầu
*in = tmp;
*in = *in>>11;
*in = *in<<27;
*in = *in>>11;
*out += *in;
}
int _tmain(int argc, _TCHAR argv[])
{
unsigned int *i, *out;
i = (unsigned int*)malloc(sizeof(unsigned int));
out = (unsigned int*)malloc(sizeof(unsigned int));
// gán giá trị cần test cho con trỏ i
*i = 0xffff;
cout<<"Input: "<<*i<<endl;
cv16to32(i, out);
cout<<"Output: "<<*out<<endl;
free(i); free(out);
return 0;
}

scooby
11-03-2010, 20:57
À, bây giờ hiểu rồi. Một bài test phỏng vấn - đánh đố. Lưu ý 4 byte là 32 bit chứ không phải là 24.

Theo kiến thức của tôi, rất tiếc là bài bạn làm không đạt yêu cầu. Bạn thể hiện bạn có hiểu về bit - byte và một vài phép toán dựa trên bit-byte, nhưng không đủ sâu.

Bạn bị các lỗi sau:
- Một khi đã bit-bite thì người ta "thường" chỉ dùng các số lũy thừa của 2 như 2, 4, 8, 16... Việc chọn các con số "lạ" như 5 và 6 chỉ chứng tỏ bạn rất ít khi làm việc với bit-byte.
- Bạn thể hiện bạn hiểu phép << và >> tốt, biết một số thủ thuật với nó. Nhưng bạn cũng để lộ điểm yếu là không biết dùng phép &, | trong trường hợp này hiệu quả hơn nhiều

- Thuật toán quá lôi thôi và dài dòng, trong khi mục đích của bạn chỉ là copy dữ liệu từ một biến sang một biến kia (mà không dùng phép gán). Hàng chục dòng của bạn chỉ công dụng tương đương một câu lệnh memcpy. Với dân C lâu năm và thường xuyên làm việc với bit byte thì memcpy luôn là lựa chọn đầu tiên

- Cái hàm void cv16to32(unsigned void *in, unsigned void *out) nếu là do bài ra thì không sao, nhưng nếu là hàm do bạn thiết kế thì đã mắc lỗi: biến in 16 bít khi gọi hàm này đã tự động được ép kiểu về 32 bít rồi. Nói cách khác bạn chẳng cần viết bất cứ cái gì nữa ngoài câu lệnh gán *out = *in;

- Nhưng điều quan trọng nhất là bạn không hiểu các biến lưu giá trị như thế nào. Nói cách khác biến 16 bit và biến 32 bit ngoài việc khác nhau về kích thước còn khác nhau cái gì nữa. Tức là bạn không hiểu phép ép kiểu thực chất làm cái gì.

(Thực ra nó cũng đơn giản thôi. Bạn sẽ tự thấy vấn đề khi lưu số âm. Cứ thử xem biến 16 bít và biến 32 bít sẽ phải đặt những bít nào khi lưu số âm như -123 chẳng hạn.)

Những ai đã ra đề dạng này thường mong chờ bạn bạn biết và làm được nhiều thứ hơn nữa.

Việc đã qua rồi, khó mà làm lại. Chỉ vài ý kiến giúp những ai muốn tìm hiểu.

phamtrungthanh
13-03-2010, 15:34
bạn vẫn chưa hiểu ý bài toán rồi
5 6 5 là số bít (tổng là 16 bít đó)
| | |
8 8 8 là sồ bít (tổng là 24 bit)

nếu 5 bít thì thêm 3 số 0 ở đầu thành 8bit
nếu 6 bit thì thêm 2 sô 0 ở đầu thành 8bit

đơn giản vậy thôi

vd:
rgb16bit thể hiện bằng kiểu int
0000 0000 0000 0000 01011 110011 01010
chuyển 24bit thành số sau (vẫn là kiểu int
0000 0000 0000 1011 0011 0011 0000 1010

còn cách kia theo bạn nói thì dùng các phép &|^~ thì cũng được thôi chỉ thêm vào một cái mặt lạ (mask)

FullOfLove
14-03-2010, 21:25
- Một khi đã bit-bite thì người ta "thường" chỉ dùng các số lũy thừa của 2 như 2, 4, 8, 16... Việc chọn các con số "lạ" như 5 và 6 chỉ chứng tỏ bạn rất ít khi làm việc với bit-byte.

cái này là chuyển từ kiểu 16 bit màu RGB 565 sang 24 bit màu thôi

phamtrungthanh
16-03-2010, 16:23
ban FullOfLove nói đúng rồi đó, ý của bài toán có vậy thôi

lqkhoi
16-03-2010, 19:54
solution
rgb24 = (uint)rgb16;
rgb24 = ((rgb24 & 0x0000f800) << 8) | ((rgb24 & 0x0x0007c0) << 4) | ((rgb24 & 0x00003f));

Số lượng bit shift có thể lệch 1 chút và không chính xác vì lười check lại. Ai rảnh confirm giùm.

@scopy: Câu này không đúng


Với dân C lâu năm và thường xuyên làm việc với bit byte thì memcpy luôn là lựa chọn đầu tiên

Không ai chơi với bit mà xài memcpy, memcpy không xài register mà sẽ kích hoạt DMA. Memcpy là 1 trong những câu lệnh rất hao CPU.