在實際生活中,很多軟體都支持打開本地磁碟已經存在的圖片,然後進行編輯,編輯完畢後,再重新保存到本地磁碟。如果使用AWT要完成這樣的功能,那麼需要使用到ImageIO這個類,可以操作本地磁碟的圖片文件。 方法名稱 方法功能 static BufferedImage read(File input) 讀 ...
大小端的概念大家都很熟悉了。
這個概念主要是針對 32bit或者 64bit機器中,多個位元組的排列順序
出處
這個詞很奇怪,查了下出處。
The Computer Science terms Big-Endian and Little-Endian were introduced by Danny Cohen 2 in 1980. The key term endian has its roots in the novel Gulliver’s Travels 3 by Jonathan Swift 4 where within a war occurs between two factions who are fighting over which end of a boiled egg should be opened for eating. The big end or the little end. Unsurprisingly, the same said book was the inspiration for the naming of the Gulliver library.
可以看到原出處是一個小說,裡面描述兩股勢力因為 吃水煮蛋應該從雞蛋的哪一端開始吃而發生了戰爭。類似於咸甜豆腐腦的爭端。
Endianness就是指雞蛋的兩頭。作者起這個名字,我猜是想代表位元組序本質上是一個沒有什麼實質意義,卻又真實存在的分歧。
具體區別
一圖流:
個人覺得小端相對來說比較符合直覺:
高位在高地址,低位在低地址。
引發的問題
主要是在32位(或者64位)的機器上,如何解釋 2位元組或者單位元組的數據。
以及一些強制類型轉換可能出現的問題
bitwise endianness bit內部的大小端
上面討論的是,64位機器內部,8個位元組的順序問題
實際上,對於一個位元組內部的Bit,也存在一個對稱的問題,bit的排列順序是怎麼樣的
給定一個結構體:
struct Byte { UINT8 bit0:1; UINT8 bit1:1; UINT8 bit2:1; UINT8 bit3:1; UINT8 bit4:1; UINT8 bit5:1; UINT8 bit6:1; UINT8 bit7:1; };
問題來了, bit 0 到底是在 Byte的 LSB還是在MSB?換個問的方法,我要修改bit 0, 是 byte |= (1 << 0), 還是 byte |= (1 << 7)
簡而言之的結論:
不確定。
C99 §6.7.2.1, paragraph 10 says:
"The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined."
C99標準表示: 具體的bit order和compiler的實現相關。
所以用bit 來表示數據的方式,相容性需要提個醒。
最安全的方式使用結構體內的成員引用方式。
如果需要顯式的表示這些位置,最好用下麵的定義方式:
1 /* Each of these preprocessor directives defines a single bit,
2 corresponding to one button on the controller.
3 Button order matches that of the Nintendo Entertainment System. */
4 #define KEY_RIGHT 0b00000001
5 #define KEY_LEFT 0b00000010
6 #define KEY_DOWN 0b00000100
7 #define KEY_UP 0b00001000
8 #define KEY_START 0b00010000
9 #define KEY_SELECT 0b00100000
10 #define KEY_B 0b01000000
11 #define KEY_A 0b10000000
12
13 int gameControllerStatus = 0;
14
15 /* Sets the gameControllerStatus using OR */
16 void KeyPressed( int key ) { gameControllerStatus |= key; }
17
18 /* Clears the gameControllerStatus using AND and ~ (binary NOT)*/
19 void KeyReleased( int key ) { gameControllerStatus &= ~key; }
20
21 /* Tests whether a bit is set using AND */
22 int IsPressed( int key ) { return gameControllerStatus & key; }
關於位運算 bitwise operation
用了很多年C,關於左移和右移操作,經常還是搞不清楚到底操作符在哪邊。
這裡一次搞明白
C99的定義:
shift-expression:
additive-expression
shift-expression
<<
additive-expression
shift-expression
>>
additive-expression
<< 或者 >>的 右側是具體移動的位數,左邊則是被操作數
x = y >> 2; // y 向右移動2位 x = y << 2; // y 向左移動2位
logical shift & arithmic shift 邏輯位移和算數位移
當位移操作和有符號數搞在一起的時候,就需要非常小心。
單純的shift我們稱作logic shift
If the variable
ch
contains the bit pattern11100101
, thench >> 1
will produce the result01110010
, andch >> 2
will produce00111001
.
上面的ch,如果以無符號數來表示,則邏輯位移不會影響語義的表達。
但是如果以有符號數表示,則從一個負數變成了一個正數。如果用作乘法操作就非常危險了。
對於C語言,左移和右移是有區別的:
- 左移永遠都是logical shift
A left shift is always a logical shift (the bits that are shifted off the end are discarded, including the sign bit).
- 右移,在unsigned時是logical shift,在signed時候是arithmic shift : 即會複製之前的符號位到最高位。
For unsigned numbers, the bit positions that have been vacated by the shift operation are zero-filled. For signed numbers, the sign bit is used to fill the vacated bit positions. In other words, if the number is positive, 0 is used, and if the number is negative, 1 is used.