c语⾔基本数据类型所占的位数
1.C++的short、int、long和long long类型通过使⽤不同数⽬的位来存储值,最多能够表⽰4中不同的整数宽度。C++提供了⼀种灵活的标准,它确保了最⼩长度(从C语⾔借鉴⽽来),如下:
1. short ⾄少16位
2. int ⾄少与 short ⼀样长
3. long ⾄少 32 位,且⾄少与 int ⼀样长
4. long long ⾄少64位,且⾄少与 long ⼀样长 (此类型为 C++11 新增,旧的编译器可能不⽀持)
2.⼀般⽽⾔,short类型为半个机器字(word)长,int类型为⼀个机器字长,⽽long类型为⼀个或两个机器字长(在32位机器中,long类型和int类型的字长通常是相同的),所以它们的表⽰范围不同。
3.short 的最⼩表⽰范围和 int ⼀样,都是-32767 到 32767 。也就是 -(2^15 - 1)到(2^15 - 1)。其中,2^15表⽰ 2 的 15 次⽅。类似地,2 的 20 次⽅记作2^20 ,以此类推。注意:C 语⾔中 2^15 并不表⽰ 2 的 15 次⽅,为了书写⽅便,我们姑且这么表⽰。
long 的最⼩取值范围是 -2147483647 到 2147483647 。也就是 -(2^31 - 1) 到 (2^31 - 1) 。unsigned short的最⼩表⽰范围和unsigned int ⼀样,都是 0 到 65535(2^16 - 1)。unsigned long 的最⼩取值范围是 0 到 4294967295(2^32 - 1)。
long long的最⼩取值范围是 -9223372036854775807(-(2^63 - 1))到 9223372036854775807(2^63 - 1);unsigned long long 是 0 到 18446744073709551615(2^64 - 1)。
⽬前,long long ⼀般 64 位,long 是 32 位,short 是 16 位,⽽ int 或者 16 位,或者 32 位。具体某个编译器到底使⽤多少位来表⽰这些类型。
4.float与double的范围和精度
1. 范围
float和double的范围是由指数的位数来决定的。
float的指数位有8位,⽽double的指数位有11位,分布如下:
float:
1bit(符号位) 8bits(指数位) 23bits(尾数位)
double:
1bit(符号位) 11bits(指数位) 52bits(尾数位)
于是,float的指数范围为-127~+128,⽽double的指数范围为-1023~+1024,并且指数位是按补码的形式来划分的。
其中负指数决定了浮点数所能表达的绝对值最⼩的⾮零数;⽽正指数决定了浮点数所能表达的绝对值最⼤的数,也即决定了浮点数的取值范围。
float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~
+1.79E+308。
2. 精度
float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是⼀个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
float:2^23 = 8388608,⼀共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字; double:2^52 = 4503599627370496,⼀共16位,同理,double的精度为15~16位。
-----------------------------我是分割线----------------------------------------------------------支持小数点的进制转换器
下⾯举例看下4.5在计算机中存储的具体数据:
Address+0 Address+1 Address+2 Address+3
Contents 0x40 0x90 0x00 0x00 接下来我们验证下上⾯的数据表⽰的到底是不是4.5,从⽽也看下它的转换过程。
由于浮点数不是以直接格式存储,他有⼏部分组成,所以要转换浮点数,⾸先要把各部分的值分离出来。
Address+0 Address+1 Address+2 Address+3
格式 SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
⼆进制 01000000 10010000 00000000 00000000
16进制 40 90 00 00
可见:
S: 为0,是个正数。
E:为 10000001 转为10进制为129,129-127=2,即实际指数部分为2。
M:为 00100000000000000000000。 这⾥,在底数左边省略存储了⼀个1,使⽤ 实际底数表⽰为
1.00100000000000000000000
到此,我们吧三个部分的值都拎出来了,现在,我们通过指数部分E的值来调整底数部分M的值。调整⽅法为:如果指数E为负数,底数的⼩数点向左移,如果指数E为正数,底数的⼩数点向右移。⼩数点移动的位数由指数E的绝对值决定。
这⾥,E为正2,使⽤向右移2为即得:
100.100000000000000000000
⾄次,这个结果就是4.5的⼆进制浮点数,将他换算成10进制数就看到4.5了,如何转换,看下⾯:
⼩数点左边的100 表⽰为 (1 × 22) + (0 × 21) + (0 × 20), 其结果为 4。
⼩数点右边的 .100… 表⽰为 (1 × 2-1) + (0 × 2-2) + (0 × 2-3) + ... ,其结果为.5 。
以上⼆值的和为4.5, 由于S 为0,使⽤为正数,即4.5 。
所以,16进制 0x40900000 是浮点数 4.5 。
上⾯是如何将计算机存储中的⼆进制数如何转换成实际浮点数,下⾯看下如何将⼀浮点数装换成计算机存储格式中的⼆进制数。
举例将17.625换算成 float型。
⾸先,将17.625换算成⼆进制位:10001.101 ( 0.625 = 0.5+0.125, 0.5即 1/2, 0.125即 1/8 如果不会将⼩数部分转换成⼆进制,请参考其他书籍。) 再将 10001.101 向右移,直到⼩数点前只剩⼀位 成了 1.0001101 x 2的4次⽅(因为右移了4位)。此时 我们的底数M和指数E就出来了:
底数部分M,因为⼩数点前必为1,所以IEEE规定只记录⼩数点后的就好,所以此处底数为 0001101 。
指数部分E,实际为4,但须加上127,固为131,即⼆进制数 10000011
符号部分S,由于是正数,所以S为0.
综上所述,17.625的 float 存储格式就是:
0 10000011 00011010000000000000000
转换成16进制:0x41 8D 00 00
-----------------------------------------------------我是分割线-------------------------------------
int,long int,short int的宽度都可能随编译器⽽异。但有⼏条铁定的原则(ANSI/ISO制订的):
sizeof(short int)<=sizeof(int)
sizeof(int)<=sizeof(long int)
short int⾄少应为16位(2字节)
long int⾄少应为32位。
下⾯给出不同位数编译器下的基本数据类型所占的字节数:
16位编译器
char :1个字节
char*(即指针变量): 2个字节
short int : 2个字节
int: 2个字节
unsigned int : 2个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
32位编译器
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
64位编译器
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论