1 byte = 8 bit
- hệ cơ số 2 sẽ được biểu diễn bằng 8 kí tự 0,1
- hệ cơ số 16 sẽ được biểu diễn bằng 2 ký tự 0,1,2,3…,8,9,a,b,c,d,e,f. 4 bit cơ số 2 = 1 ký tự 0-f ở cơ số 16.
- hệ cơ số 10 sẽ được biểu diễn bằng (tối đa) 3 ký tự 0-9.
0x01 = 0b00000001
= 1*16^0 + 0*16^1 = 1
0xff = 0b11111111
= 15*16^0 + 15*16^1 = 255
với số nguyên có dấu thì 0xFF
sẽ được hiểu theo nghĩa khác. Để tiện cho phép cộng khi 1 số nguyên 8 bit x cộng với 1 số nguyên 8 bit y nếu x = -y thì x + y = 0, máy tính sẽ cho giá trị của số nguyên có dấu theo quy tắc bù 2: nếu bit cao nhất của x là 1 thì giá trị của x là trừ của (x đảo bit) + 1:
0xFF = 0b11111111
đảo bit 1 thành 0, 0 thành 1:
0b00000000
cộng 1:
0b00000001 = 1
vậy giá trị của số nguyên có dấu 0xFF là -1
tính tiện lợi của quy tắc bù 2: lấy 0xFF + 0x01 = 0
0b11111111
+ 0b00000001
=0b100000000 số 1 bị bỏ đi vì nó vượt quá 8 bit, còn lại 0b00000000 = 0
số nguyên có dấu int 32 bit = 4 byte = biểu diễn với 8 ký tự trong hệ cơ số 16, 32 ký tự trong hệ cơ số 2 (tối đa 10 ký tự trong hệ cơ số 10)
0x01010101 = 0b00000001.00000001.00000001.00000001
(viết thêm dấu . cho dễ nhìn), bit cao nhất (bên trái) = 0, tính giá trị bình thường: 1*16^0 + 0*16^1 + 1*16^2 + 0*16^3 + 1*16^4 + 0*16^5 + 1*16^6 + 0*16^7 = 1 + 256 + 65536 + 16777216 = 16843009
0xFFFFFFFF = 0b11111111.11111111.11111111.11111111
, bit cao nhất (bên trái) = 1, áp dụng quy tắc bù 2 tính giá trị là -1
trong trang cplusplus kia có ghi rõ ràng mà ko đọc kĩ à :V
The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value .
dù được pass là int nhưng memset
sẽ chuyển giá trị này thành unsigned char
, ở đây là unsigned int 8 bit. 0x00000001 (1) sẽ được convert thành 0x01 (1). 0xffffffff (-1) sẽ được convert thành 0xff (255 vì ko dấu).
-
memset copy vào 20 bytes kia giá trị 0xff thì 20 bytes đó đều có giá trị là 0xff:
[0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff][0xff]
hay ở dạng binary
[11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111][11111111]
sau đó printf ra thì a[i] lại được hiểu là int có dấu 4 byte:
[11111111.11111111.11111111.11111111][11111111.11111111.11111111.11111111][11111111.11111111.11111111.11111111][11111111.11111111.11111111.11111111][11111111.11111111.11111111.11111111]
hay ở hệ cơ số 16
[0xffffffff][0xffffffff][0xffffffff][0xffffffff][0xffffffff]
đều có giá trị -1 hết
-
memset copy vào 20 bytes kia giá trị 0x01 thì 20 bytes đó đều có giá trị là 0x01:
[0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01][0x01]
hay ở dạng binary
[00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001][00000001]
sau đó printf ra thì a[i] lại được hiểu là int có dấu 4 byte:
[00000001.00000001.00000001.00000001][00000001.00000001.00000001.00000001][00000001.00000001.00000001.00000001][00000001.00000001.00000001.00000001][00000001.00000001.00000001.00000001]
hay ở hệ cơ số 16
[0x01010101][0x01010101][0x01010101][0x01010101][0x01010101]
đều có giá trị là 16843009
nếu thử gán với -2 = 0xfffffffe thì memset sẽ convert nó thành 0xfe (254) rồi gán vào từng byte. a[i] sẽ có giá trị 0xfefefefe = -16843010 (vì 0xfefefefe + 0x01010101 = 0xffffffff = -1 nên suy ra 0xfefefefe = -1 - 0x01010101 :V Nếu tính bù 2 cũng được: đảo bit 0xfefefefe = 0x01010101 = 16843009, cộng 1 = 16843010, vậy kết quả là -16843010)
còn có vụ endianess little/big endian nữa nhưng vì ở đây 4 byte của int 32 bit đều giống nhau nên ko quan trọng :V