Chủ đề: Một số về bitwise operators
-
20-07-2007, 12:28 PM #1Administrator
- Ngày tham gia
- Feb 2014
- Bài viết
- 0
Một số về bitwise operators
Một số chú ý về ' Bitwise Operator '
----------------------------------------------------
Các phép toán trên bit :
_bitwise AND ( & )
_bitwise OR ( | )
_bitwise XOR ( ^ )
_bitwise NOT ( ~ )
_left shift ( << )
_right shift ( >> )
Tóm tắt một chút :
1. Bitwise AND ( & )
Chú ý đây là phép toán chỉ áp dụng trên bit cần phân biệt với &&, đây là so sánh toán tử điều kiện
Bảng giá trị :
0 & 0 = 0 : 1 & 0 = 0 : 0 & 1 = 0 : 1 & 1 = 1
Ví dụ : 01101111 & 11110000 = 01100000
So sánh AND ( & ) từng bit tương ứng ( cùng vị trí hay vị trí tương ứng trong byte )
Thêm một ví dụ khác :
$result = 124 & 99;
Chuyển sang hệ BIN, nhị phân.
124D = 01111100B
99D = 01100011B
D = Decimal : Hệ thập phân (base-10)
B = Binary : Hệ nhị phân (base-2)
So sánh từng vị trí bit trong byte theo AND ( & ) thu được
$result = 96 ( = 01100000B)
2.Các toán tử khác OR , XOR , NOT :
OR ( | ) : Bảng giá trị :
0 | 0 = 0 : 0 | 1 = 1 : 1 | 0 = 1 : 1 | 1 = 1
XOR ( ^ ) : Bảng giá trị :
0 ^ 0 = 0 : 0 ^ 1 = 1 : 1 ^ 0 = 1 : 1 ^ 1 = 0
NOT ( ~ ) :
~1 = 0 : ~0 = 1
3.Hai phép dịch bit : left-shift và right-shift :
Ví dụ :
$result = $x >> 1 ;
mang ý nghĩa : các bit của $x dịch sang phải 1 bit. <hơi khó hiểu>.
Cụ thể :
$result = 99 >> 1 ;
mang ý nghĩa : các bit của 99 dich sang phải 1 bit.
Từ từ thực hiện :
chuyển sang hệ nhị phân (binary) : 99D = 01100011B [X]
dịch sang phải 1 bit tức là : 00110001 [Y]
So sánh 2 số tại [X] và [Y] để ý thấy :
từ [X] sang [Y] : bit cuối cùng biến mất và thêm vào đầu là 0 thay thế bit vị trí đầu tiên.
Có thể hiểu đơn giản : là xóa bit cuối cùng đi và lấp đầy khoảng trống ( thêm 0 vào đầu bit )
Kết quả : $result = 49 ( = 00110001B )
Tổng quát hơn : $result = $x >> n ;
mang ý nghĩa : dịch các bit của $x sang phải n bit ( = n vị trí ), thay thể các vị trí trống = 0
Các ví dụ trên dùng số nguyên 8-bit.
Với các bit lớn hơn 16-bit, 32-bit tương tự bạn chỉ cần thêm 0 cho đủ số bit tương ứng.
Một điều chắc chắn là : giả sử $x là số nguyên k-bit thì khi $x >> n với n >= k kết quả thu được luôn là 0.
Chú ý khác :
1). Để ý ví dụ sau :
$x = 17 >> 1;
$y = 16 >> 1;
So sánh $x và $y ?
17D = 00010001B;
16D = 00010000B;
Ái dà : kết quả thu được $x = $y = 8;
--> Cái này hay nhỉ [IMG]images/smilies/biggrin.png[/IMG]
2). Không nên dịch bit quá lớn, vượt quá giới hạn cho phép.
Giả sử bạn dùng 16-bit với phép tính : $result = 35000 << 1;
kết quả tính ra thu được 70000 , nghĩ là thế nhưng thực tế là lỗi
vì giới hạn 16-bit max = 65536.
3). Dịch bit và Lũy Thừa cơ số 2 : [IMG]images/smilies/biggrin.png[/IMG]
so sánh 2 cái này phát :
$x = 99 >> 1;
$y = 99 /2;
Kết quả : $x = $y = 49 ; bằng nhau
làm phép tính khác ;
$x = 99 << 1;
$y = 99 * 2;
Kết quả : $x = $y = 198; bằng nhau
Tóm lại có được quy luật chuyển bit [IMG]images/smilies/biggrin.png[/IMG]
_Dịch sang trái n bit với n là số nguyên dương thì tương đương với nhân với 2 lũy thừa n
_Dịch sang phải n bit với n là số nguyên dương thì tương đương với chia với 2 lũy thừa n
Thành ra dùng quy tắc chuyển dịch trên nhanh hơn cứ ngồi convert rồi dịch bit [IMG]images/smilies/biggrin.png[/IMG]
Kiến thức nho nhỏ, viết lại chia sẻ chút ^_^!
Written by PeteView more random threads:
- Định hướng nghề nghiệp: nên theo lập trình hay kinh tế :(
- Học chuyên sâu về lập trình Linux
- Ngôn ngữ lập trình nào hot nhất hiện nay???
- Đại lý sửa máy giặt hãng Toshiba tại nhà Huyện Thanh Trì
- TT Bảo hành tivi Toshiba LCD 56 inch tại Tỉnh Bắc Giang - với ngân sách thấp
- Nên chọn hướng đi nào cho học sinh lớp 12 theo ngành CNTT?
- Giữa phát triển ứng dụng và phát triển game thì ngành nào đang HOT hơn nhỉ?
- Tư vấn chọn ngôn ngữ lập trình
- Cung cấp phân hữu cơ nhật số lượng lớn
- Sinh viên ra trường cần trang bị kiến thức gì ?
-
20-07-2007, 12:32 PM #2Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
!!^_^!! Lâu lâu post 1 bài ra trò đấy [IMG]images/smilies/biggrin.png[/IMG],
_Dịch sang trái n bit với n là số nguyên dương thì tương đương với nhân với 2 lũy thừa n
_Dịch sang phải n bit với n là số nguyên dương thì tương đương với chia với 2 lũy thừa n
-
02-06-2008, 06:49 PM #3Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Cám ơn bác Xcross87 nhé. Em đang tìm hiểu cái này coi bài của bác thì ko thể chê vào đâu được.
-
27-10-2008, 08:18 AM #4Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Nói về bitwise là người ta thường nhắc đến số nguyên dương chứ có phải mấy trường hợp của các bác đâu trời -_-;;
-
27-10-2008, 09:02 AM #5Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Trường hợp 1 của tui là nguyên dương đó chớ. Và ứng dụng của tui cũng đòi phải làm vậy đó chớ. (1 << 32 = 1!!!).
Mới thử lại bên g++, nó cho 1 warning và cũng cho ra 1 << 32 = 1 (nhưng (1 << 16) << 16 thì đúng = 0 ^^).
-
27-10-2008, 09:40 AM #6Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi hieusua
- Đọc cái chú ý 2: giời hạn dịch bit [MỞ MẮT CHO TO RA RỒI ĐỌC]
- Bài này tôi để TITLE là "MỘT SỐ VỀ BITWISE" chứ không phải TẤT CẢ VỀ BITWISE
Nếu cậu giỏi, thích văn vẹo người khác thì sao không làm hẳn một bài hướng dẫn chia sẻ mọi người đi.
-
27-10-2008, 10:02 AM #7Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Trước tiên, xin lỗi vì mấy bài post kia làm bạn nổi nóng. Nhưng mình không thích vặn vẹo người khác kiểu này (nhất là với những bạn nhiệt tình - bạn review lại các post của mình sẽ thấy). Thiệt tình, tại diễn đàn không có nút Thanks, chứ không mình đã Thanks bạn trước khi post mấy post kia thì chắc bạn không hiểu lầm vậy.
Số nguyên âm thì mình hoàn toàn đồng ý là nó ít khi được làm việc với các toán tử xử lý bit.
Còn trường hợp kia, vì cái mình làm cũng có dính nhiều tới bitwise, nên mình hay gặp nó, và chưa giải thích được vì sao nó thế, chỉ định post lên và hỏi bạn (và mấy bạn khác) xem vì sao thôi mà (với lại để mấy bạn khác lưu ý về trường hợp đặc biệt này). Và mình cũng xin lỗi vì cái ví dụ mình đưa ra là SAI. Mình đặt lại vấn đề thế này:
Mã:int a, b; a = 1; b = a >> 32;
-
27-10-2008, 10:18 AM #8Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi hieusua
Bạn thử cho nó dịch phải 31 nháy và 1 nháy xem nó ra bao nhiêu...
Tớ test thử:
Mã:#include <stdio.h> int main(void){ int a, b; a = 1; b = a >> 1; printf("1 bit:\t b = %d ", b); b = a >> 2; printf("2 bit:\t b = %d ", b); b = a >> 31; printf("31 bit:\t b = %d ", b); b = a >> 32; printf("32 bit:\t b = %d ", b); b = a >> 33; printf("33 bit:\t b = %d ", b); return 1;}
Mã:1 bit: b = 02 bit: b = 031 bit: b = 032 bit: b = 133 bit: b = 0Press any key to continue . . .
Mã:1 bit: b = 1 2 bit: b = 0 31 bit: b = 0 32 bit: b = 3 33 bit: b = 1 Press any key to continue . . .
Đưa ra kết luận:
+ Nếu giới hạn dịch vượt quá kích thước của kiểu dữ liệu thì phép dịch sẽ bị luân hồi, tức là dịch lại từ đâu.
Ví dụ: kiểu int = 4 bytes = 32 bits => dịch tối đa 31 nháy (0->31). Từ 32 trở lại nó sẽ dịch ngược lại từ đầu tức là: a >> 0 == a >> 32; a >> 1 == a >> 33 .... (==: kí hiệu tương đương).
Test thử sẽ rõ:
Mã:#include <stdio.h> int main(void){ char a = 13; if((a >> 1) == (a >> 33)) printf("TRUE "); return 1;}
-
27-10-2008, 10:30 AM #9Silver member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
ps hieusua : Một thắc mắc, cậu không hiểu int có 1 bit cuối là âm hay dương làm sao cậu viết ra đoạn code này nhỉ ?
Mã:int abs(int in) { return ((in ^ 0xffffffff) + 1);}
-
27-10-2008, 11:11 AM #10Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
@X: Hiểu rùi. Có lẽ do môi trường 32 bit nên nó không cho dịch quá 32 bit.
Câu lệnh:
a << b ; a >> b;
Sẽ thành:
a << (b % 32); a >> (b % 32);
(Mình thử với kiểu char và short khi dịch quá 8 bit hay 16 bit đều ra 0 -> đúng).
@r2: Mình post xong 1 lúc mới thấy sai, mà chưa kịp sửa :P
Khu chung cư FLC SeaTower Quy Nhơn được xây dựng bởi Keppel Land căn hộ đa năng sống trẻ trung công viên tích hợp. FLC SeaTower Quy Nhơn giagocchudautu.com căn hộ đa năng cây xanh rộng không gian...
FLC SeaTower Quy Nhơn Dự án chung...