資料型別轉化
c/c++
type
lenbool
1byte
char
1byte
short
1byte
int4byte
long
4byte
float
4byte
double
8byte
乙個位元組有8位 28=256
整數7用二進位制表示為
0000 0111
+ ?||
0000 0000
為了簡單的使7 + (-7) = 0, -7 二進位制表示為 1111 1001。也就是我們經常說的負數的二進位制表示為正數的反碼加1。
推導過程
0000 0000 0000 1111 (15)
1111 1111 1111 0000 (15的反碼)
1111 1111 1111 1111 (加上1就可以導致資料溢位,8位清零)
0000 0000 0000 0001 (-15 表示為 1111 1111 1111 0001)
0000 0000 0000 0000 (0)
ansi/ieeestd 754-1985標準
ieee 754是最廣泛使用的二進位制浮點數算術標準,被許多cpu與浮點運算器所採用。ieee754規定了多種表示浮點數值的方式,在本文件裡只介紹32bits的float浮點型別。它被分為3個部分,分別是符號位s(sign bit)、指數偏差e(exponent bias)和小數部分f(fraction)。
其中s位佔1bit,為bit31。s位為0代表浮點數是正數,s位為1代表浮點數是負數,比如說0x449a522c的s位為0,表示這是乙個正數,0x849a522c的s位為1,表示這是乙個負數。
e位佔8bits,為bit23~bit30。e位代表2的n次方,但需要減去127,比如說e位為87,那麼e位的值為2(87-127)=9.094947017729282379150390625e-13。
f位佔23bits,為bit0-bit22。f位是小數點後面的位數,其中bit22是2-1=0.5,bit21是2-2=0.25,以此類推,bit0為2-23=0.00000011920928955078125。但f位里隱藏了乙個1,也就是說f位所表示的值是1+(f位bit22~bit0所表示的數值),比如說f位是0b10100000000000000000001,只有bit22、bit20和bit0為1,那麼f位的值為1+(2-1+2-3+2-23),為1.62500011920928955078125。
綜上所述,從二進位制數換算到浮點數的公式為:(-1)s×2e-127×1.f。
舉個換算的例子:
下面來看看浮點數與二進位制數如何轉換。
二進位制數換算成浮點數:
假如在記憶體中有乙個二進位制數為0x449a522c,先將十六進製制轉換成二進位制,如下:
0100 0100 1001 1010 0101 0010 0010 1100
按照sef的格式分段,如下:
0 10001001 00110100101001000101100
這個數值不是特殊的情形,可以按照公式(-1)s×2(e-127)×(1+f)轉換。s位的值為(-1)0=1,e位的值為2137-127=1024。f位的值為1+2-3+2-4+2-6+2-9+2-11+2-14+2-18+2-20+2-21= 1.205632686614990234375。最終結果為1×1024×1.205632686614990234375=1234.56787109375。
其中f位比較長,使用二進位制方式轉換比較麻煩,也可以先轉換成十六進製制再計算,轉換為十六進製制如下:
0011 0100 1010 0100 0101 1000
0x3 0x4 0xa 0x4 0x5 0x8
f位為23bits,需要在最後補乙個0湊成24bits,共6個十六進製制數。f位的值為1+3×16-1+4×16-2+10×16-3+4×16-4+5×16-5+8×16-6=1.205632686614990234375,與上面使用二進位制方法得到的結果相同。
char ch =
'a';
short s = ch;
printf
("s is %d\n"
, s)
;
程式列印結果:
s is 65
從記憶體的角度分析,char型資料佔乙個位元組,short佔兩個位元組,把ch 賦值給s,ch的8位複製到s低8位,s的高8位為0,表示為 0000 0000 0100 0001。
short sh =
512;
char ch1 = sh;
printf
("ch1 = %d\n"
, ch1)
;
程式列印結果為:
ch1 =
0
從記憶體角度分析,short佔2個位元組 也就是16byte,0010 0000 0000,char佔乙個位元組8byte, 將short型的sh賦值給char型ch1,實際上賦值的是sh的低8位 0000 0000。所以ch1 的列印結果為0。
int t =
1782579
;short s1 = i;
printf
("s1 = %d\n"
, s1)
;
程式執行結果:
s1 =
2097
從記憶體的角度分析,int型的i賦值給short型的s1,實際上是將t的低16位複製給s1。
41
short ss =-1
;42int ii = ss;
43printf
("ii = %d\n"
, ii)
;
程式執行結果:
ii =
-1
從記憶體角度分析,ss 為1111 1111 1111 1111,將ss 賦值給ii,將16位複製到ii的低16位,然後進行符號擴充套件, ii 為 1111 1111 1111 1111 1111 1111 1111 1111。
45
int a =5;
46float f = a;
47printf
("f = %f \n"
, f)
;
程式執行結果:
f =
5.000000
為什麼是5.0, 實際上int 5被翻譯成1.25 * 22, 套用公式「(-1)s * 1.***x * 2exp-127」可以得出 s=0,***x=0.25, exp = 129, 根據這些值可以畫出float f的記憶體結構圖 0 1000 0001 0100 000 …0 。
再看乙個例子:
49
int b =37;
50float c =*(
float*)
&b;51
printf
("c = %f\n"
, c)
;
程式執行結果:
c =
0.000000
為什麼會是0呢?作業系統將指向(int *)的位址認為是指向(float * ),所以對於b所指向的四個位元組的空間會按float型別翻譯,32 剛好位於 f區域,翻譯成float型資料會是乙個很小的資料。
53
float d =
7.0;
54short e =*(
short*)
&d;55
printf
("e = %hd\n"
, e)
;
程式執行結果:
e =
0
浮點型資料型別
double 和 float 資料型別都是浮點型,在從記憶體中取出來後,即便之前的賦值是個 整型的資料型別,把浮點型取出來後都會變成實數的小數,比如賦值為0,取出來後就是0.0了 float var f 0 double var d 0 system.out.println var f 0.0 sy...
基本資料型別 浮點型 指標
浮點數家族包括float double和long double型別。通常,這些型別分別提供單精度 雙精度以及在某些支援擴充套件精度的機器上提供擴充套件精度。ansi標準僅僅規定long double至少和double 一樣長,而double至少和float一樣長。標準同時規定了乙個最小範圍 所有浮點...
MATLAB的資料型別整型和浮點型
可以看出matlab的數值型別跟c語言一樣分為整型和浮點型,但是需要特別注意的是,它的用意和c語言完全不一樣。前者的整型資料主要為影象處理等特殊的應用問題提供資料型別,而對於一般數值運算,絕大多數是採用雙精度浮點型的資料。8種整數型別 整數型別 數值型別 轉換函式 有符號8位 2 7 2 7 1 i...