以上是一個簡單的 C 語言 casting,把無號數轉換成浮點數
可以看到儘管表示同一個數字,但是實際上在不同資料型態間二進位表示是完全不同的,這也是為什麼在 C 語言中我們需要透過 Casting 強制轉型才能讓一個數值在不同資料型態間轉換
不過你有想過,強制轉型底層是怎麼實做的嗎?
char
to int
與 short
to int
char
形態用int
Double WORD (4 BYTE) 的方法取出。short
形態用int
Double WORD (4 BYTE) 的方法取出。int
to float
int 轉換成 float 就比較困難,float 因為遵守 IEEE 754 的規定雖然可以表示小數點但是數值的表示變得複雜
下面是利用 godbolt 所產生的組合語言
cvtsi2ss 即是把int
轉換成float
的 x86 指令,這個指令的全名是
CVTSI2SS — Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value
也就是用一個指令來 convert。至於實作就看各家晶片製造商的做法。
xmm1 這個暫存器也很有趣,根據維基百科的敘述,xmm1 是在 SSE ( Streaming SIMD Extensions ) 指令集的時候加入的暫存器,有 128 bits 可以進行單指令多資料的操作。
除了資料型態轉換可能會改變原始資料儲存方式,C 語言中的「型別修飾字」(qualifiers)會不會也會影響呢?
int
to unsigned int
事實上,這邊印出來的 hex 型態都是相同的 0xfffffff6
其實 unsigned
這樣的修飾字並不會影響資料數值,不過在讀取的時候對同一筆資料的解讀方式會不一樣
C99 規格書裡面應該可以找到 reference,我是找
type qualifier
不過符合的量還是太多 陳奕熹
int
and const int
十分意外的,這是編譯後的結果
a = a, &a = 7fffffffdd90
b = a, &a = 7fffffffdd94
/* 用 gdb 看 stack pointer 在 7fffffffddb0 */
a, b在二進制時表現相同這點,從前面的 unsigned
部份就可以理解到二進制不會被改動
不過令人意外的是,被標記為 const
的資料並不會被存到下面 C語言記憶體配置圖中的 text
區域
有趣的是,從編譯出來的組合語言可以知道,事實上
兩者在完全沒做最佳化(-O0)時,編譯的結果就已經一樣了