Chủ đề: Một số về bitwise operators
-
20-07-2007, 12:28 PM #1
Administrator
- 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:
- Hãy cho mình điểm bắt đầu để tiếp cận OPENGL
- Chọn nghề nào để có công việc ổn định
- Kinh nghiệm đọc source code
- AMDI GREEN CITY Cuộc sống xanh, An lành, Thịnh vượng!
- Cung cấp phân hữu cơ nhật số lượng lớn
- suy ngẩm về lập trình
- Hiểu thế nào về lập trình hướng đối tượng ???
- Lập Trình Web Chuyên Nghiệp Nên sử Dụng Tool Hay Code Chay?
- Muốn làm lập trình viên thì nên học chuyên ngành nào?
- Gameloft recruit Rich Media Programmer
-
20-07-2007, 12:32 PM #2
Junior 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],
Đôi khi lối suy nghĩ đơn giản lại giúp ích, lúc học hợp ngữ, tớ cũng ghét ba cái vụ dịch chuyển bit này lắm, nhưng nhờ nghĩ đơn giản như vậy nên .... [IMG]images/smilies/applause.gif[/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 #3
Junior 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 #4
Junior 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 #5
Junior 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 #6
Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Này, tôi không biết cậu giỏi thế nào chứ. Cậu đọc hết từng chữ của bài tôi viết chưa ???
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 #7
Junior 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:
Vì mình rất thích bitwise, nên thay vì đem chia, mình thường xài phép dịch bit. Ở đây đáng lẽ ra "a >> 32" thì bằng "a / (2^32)", rõ ràng luôn = 0 (và không vi phạm cái giới hạn ở chú ý 2 bạn đưa ra). Mà tại sao nó vẫn là 1? g++ cho 1 warning: right shift count >= width of type. Mình nghĩ là khi right shift >= max bit của biến thì nó sẽ không dịch nữa, nhưng nếu vậy thì hơi củ chuối nhỉ?Mã:int a, b; a = 1; b = a >> 32;
-
27-10-2008, 10:18 AM #8
Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
biến kiểu int trong g++ là 4 bytes (32 bit) => right shift tối đa là 31 nháy.
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ử:
Kết quả: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;}
Thử lại với giá trị khác: lấy a = 3: thì kết quả là:Mã:1 bit: b = 02 bit: b = 031 bit: b = 032 bit: b = 133 bit: b = 0Press any key to continue . . .
Thay với bất kì giá trị nào của a cũng đều thế này.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õ:
OK?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 #9
Silver 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 #10
Junior 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


Trả lời kèm Trích dẫn
ADTIMIN tiếp tục khẳng định vị thế của mình thông qua việc đầu tư mạnh mẽ vào hạ tầng máy chủ và hệ thống quản trị công nghệ tiên tiến, tạo ra môi trường lưu trữ tối ưu đáp ứng mọi nhu cầu đa dạng...
Giải pháp công nghệ tối ưu cho...