1.byte的大小为8bits而int的大小为32bits
- k! A/ Y5 r) ?/ T" b# |0 R
' X0 `" m, u+ D% R" \ S0 J3 _ 2.java的二进制采用的是补码形式
* i& [& W* [. f9 y6 {& `3 I" Y2 e, ^; e ' a; Z. t4 }, K9 P) J! \4 X6 f5 x
在这里先温习下计算机基础理论1 N( @$ H4 O- I; q7 G5 w
- V7 d* l6 \4 l/ j) p
byte是一个字节保存的,有8个位,即8个0、1.+ }" ?4 [# o/ ^% U
3 s" X4 F! P: e# i 8位的第一个位是符号位,4 H" x; d) R8 r8 x: k C) T
; O# ?9 h8 b; Y# U6 E) N$ n
也就是说0000 0001代表的是数字1
- R# t& S$ e% T% N3 g: M
3 Z) s" k2 A C( j 1000 0000代表的就是-17 t. b# e; U, E" e Q# `
2 q" h' t) s- ]9 c
所以正数最大位0111 1111,也就是数字127
; T! }8 l l. ]5 c" {* ^
Q) k- l+ P# n, T1 z5 B 负数最大为1111 1111,也就是数字-128 W* Z5 P1 L: N L6 h9 s+ Q
. A; X* r X3 v4 U
上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码; J6 }7 s. V- Y& j4 F! A( I# r
. w6 s2 w9 J/ R, q3 I0 s
1、反码:; q# H( ] p& O4 A7 a
h7 w" {4 D) B 一个数如果是正,则它的反码与原码相同;& r* A) b, ?. J6 [
) b, N+ _. a# T! ]* E" y 一个数如果是负,则符号位为1,其余各位是对原码取反;2 U# E& V" y2 j+ l" G
0 t3 m; d+ n, _* G7 ]2 E" O
2、补码:利用溢出,我们可以将减法变成加法& S+ I r! Z0 R; u1 a1 o1 y
I+ }; L/ V8 H }8 T! ]. c5 o 对于十进制数,从9得到5可用减法:
8 r3 z$ I& Y9 j' x8 T
+ D( @" Z+ e& v: I$ ?: v 9-4=5 因为4+6=10,我们可以将6作为4的补数3 F w- q0 m$ D/ m. a- |
$ W& @: z2 V4 u! O: e" k( y9 A s- E7 t 改写为加法:) [& D9 W$ d) s" [ e9 V6 a
- j+ C) }7 c; ]/ I
9+6=15(去掉高位1,也就是减10)得到5.. B# K7 {) R- q
5 V0 P/ a/ O. ^ 对于十六进制数,从c到5可用减法:
; D2 b5 {" { J. j0 v 5 ^# R7 w0 E7 c1 U
c-7=5 因为7+9=16 将9作为7的补数
' _* Z# H4 f' y/ N3 g+ n8 m2 y
3 w$ \/ }" D& Q2 O0 t 改写为加法:
+ |% y: Q3 i5 G0 u; n 9 w0 y9 H3 K/ e5 p! B
c+9=21(去掉高位1,也就是减16)得到5.
" O" @8 R; f! E5 S , ^. u3 ?2 @ N2 [) s
在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。8 F- c9 ? i8 r4 A G
+ V, M9 K; m9 U4 {8 p: @ ⑴一个数为正,则它的原码、反码、补码相同9 A1 X: Q9 |+ V. B% ~7 l+ E
( P% u% j7 ]1 `) @' d# e
⑵一个数为负,刚符号位为1,其余各位是对原码取反,然后整个数加1
) ] {, t5 P) I
1 e7 j2 s ~5 {% M: [. g+ K - 1的原码为 10000001
* M! ?: L0 r. g2 w4 W8 f D7 K 8 G. a& |9 F1 j
- 1的反码为 11111110
# v5 X' L6 b. z% \- e' K* q8 ?& H : A! x: u# b+ O" ~1 I |
+ 1
3 N' g& x; V, f& O- R
7 H" q" E% Y# c/ w* y - 1的补码为 11111111" A2 l, {9 E9 ~! C- H1 \, Q; r
" O1 F* a+ L4 C! \ 0的原码为 00000000
7 V1 ]7 @ u: v$ d d, i1 k' F8 U
$ H& ]$ N3 p; c" o 0的反码为 11111111(正零和负零的反码相同)
+ i8 @. \# H" v8 p; E1 L9 M6 W
! ]7 K9 j) j5 Z5 H9 z/ Y) m +1
5 Y" p, Q! r7 G4 X7 J
" U. @1 r" s( Y" ` 0的补码为 100000000(舍掉打头的1,正零和负零的补码相同)2 f4 D' s5 R& ]( h; r# ^
2 j9 _- {, ~$ b
Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,/ K5 {. o; f/ s
* ^4 p$ B7 h% d! |+ E 例如补码11111111的十进制数为-1转换为int时变为11111111111111111111111111111111好多1啊,呵呵!即0xffffffff但是这个数是不对的,这种补位就会造成误差。; H Z7 X2 c, M, v" `, G: c n G
- R! m! |5 x* c$ B0 _8 P
和0xff相与后,高24比特就会被清0了,结果就对了。
. l- U g# s! \. F0 q& R9 N' C 5 {; O/ z% S3 y0 j2 x6 x' X3 K1 G) O
----
/ |! D; E) p# [0 ]7 \& e: t 9 S) V$ R) Y6 L6 [
Java中的一个byte,其范围是-128~127的,而Integer.toHexString的参数本来是int,如果不进行&0xff,那么当一个byte会转换成int时,对于负数,会做位扩展,举例来说,一个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。
8 h/ a* ~( l+ u! P& Y! o! { 0 u/ k. f/ r s; X* G
而0xff默认是整形,所以,一个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的高的24个比特就 |