精华内容
下载资源
问答
  • 搞透C语言整型数据范围表示

    千次阅读 2017-08-26 18:04:52
    C语言中,整型数据类型的取值范围计算方法,类似的可得出都出double和float的范围计算方法

    (1)short

    C语言中,short是定义一种整型变量家族的一种

    长度

    依据程序编译器的不同short定义的字节数不同。

    标准定义short短整型变量不得低于16位,即两个字节。

    编译器头文件夹里面的limits.h定义了short能表示的大小:SHRT_MIN~SHRT_MAX。在32位平台下如windows(32位)中short一般为16位。

    若规定编译器规定short为2字节,则:

    unsigned short i; i可以表示0~65535(0~2^16-1)
    signed(默认)short i; i可以表示-32768~+32767(-2^(16-1)~2^(16-1)-1)

    (2)int

    C语言中,int是定义一种整型变量家族的一种。

    长度

    目前在一般的电脑中,int占用4字节,32比特,数据范围为-2147483648~2147483647[-2^31~2^31-1]
    在之前的微型机中,int占用2字节,16比特,数据范围为-32768~32767[-2^15~2^15-1]
    unsigned int 表示无符号整数,数据范围为[0~2^32-1]


    除了short、int类型之外,还有long、long long类型可以表示整数。

    以下对范围求取进行说明。


    图1

    以8位进行说明,16位,32位,64位类似。

    第一位为符号位,0正,1负。假定数据类型的长度为一个字节8位。对有符号整型进行说明。

    (1)有符号

    对于负数的下限,最高位作为符号位位1,用1 1 1 1 1 1 1 1,如图1所示。即为-127,而不是-128,

    难道是1 0 0 0 0 0 0 0?其实就是用1 0 0 0 0 0 0 0表示-128的。以下进行说明。

    注意:1000 0000 B 不等于0 而是 -128(图2)
    +127 +1 = -128
    即 0111 1111 B+1 = 1000 0000 B
    也就是发生了 byte值溢出
    8位二进制反码的表示范围:-127~+127
    为什么 -128 的二进制会是1000 0000;
    1000 0000 (原) = 1111 1111(反)
    那么问题来了: 64+32+16+8+4+2+1 = 127 为什么会有128呢?
    原来 负数 反码是需要补码的,也就是在最后得出的结果上 +1
    注意:计算机中只有 +0 而不存在 -0的说法,因为-0是完全没有意义的存在(见下对正0负0的说明),
    即:只有 0000 0000 = +0
    而没有 1000 0000 = -0
    1000 0000的真实身份是 -128 


    图2

    需要了解计算机对数据的存储表示方法(原码、反码、补码),以及负0与正零的表示。

    (1)所谓原码就是前面所介绍的二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。

    反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。

    补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。


    原码不能直接参加运算,可能会出错。例如数学上,1+(-1)=0,而在二进制中00000001+10000001=10000010,换算成十进制为-2。显然出错了。所以原码的符号位不能直接参与运算,必须和其他位分开,这就增加了硬件的开销和复杂性。为了解决原码做减法的问题,出现了反码:计算十进制的表达式: 1-1=01 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原=[0000 0001]反 + [1111 1110]反 =[1111 1111]反 = [1000 0000]原 =-0    发现用反码计算减法,  结果的真值部分是正确的. 。而唯一的问题其实就出现在"0"这个特殊的数值上.虽然人们理解上+0和-0是一样的。但是0带符号是没有任何意义的.而且会有[0000 0000]原和[10000000]原两个编码表示0.于是补码的出现,

    反码是数值存储的一种,多应用于系统环境设置,如linux平台的目录和文件的默认权限的设置umask,就是使用反码原理。

    在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。负数的补码则是符号位为“1”。并且,这个“1”既是符号位,也是数值位。数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。
    补码的出现,解决了0的符号以及两个编码的问题:1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 =[0000 0001]补 + [1111 1111]补 =[0000 0000]补=[0000 0000]原  ,这样0用[0000 0000]表示,而以前出现问题的-0则不存在了.而且可以用[10000000]表示-128:(-1) + (-127) = [1000 0001]原 + [1111 1111]原 =[1111 1111]补 + [1000 0001]补 =
    [1000 0000]补

    -1-127的结果应该是-128,在用补码运算的结果中, [1000 0000]补 就是-128.但是注意因为实际上是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示.(对-128的补码表示[10000000]补算出来的原码是[0000 0000]原,这是不正确的)使用补码, 不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数.

    这就是为什么8位二进制,使用原码或反码表示的范围为[-127, +127],而使用补码表示的范围为[-128, 127].因为机器使用补码,所以对于编程中常用到的32位int类型,可以表示范围是: [-2^31, 2^31-1]因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.


    (2)根据原码的定义:正零和负零的原码为:

    +0 : 0000 0000 0000 0000 0000 0000 0000 0000 (32 bit)

    -0 : 1000 0000 0000 0000 0000 0000 0000 0000



    而反码为:

    +0 : 0000 0000 0000 0000 0000 0000 0000 0000

    -0 : 1111 1111 1111 1111 1111 1111 1111 1111

    补码为:

    +0 : 0000 0000 0000 0000 0000 0000 0000 0000

    -0 : 1 0000 0000 0000 0000 0000 0000 0000 0000

    可以看出,-0的补码发生溢出,舍弃最高位后,其跟+0在内存的表示一样,都是:

    0000 0000 0000 0000 0000 0000 0000 0000


    再看看下面的图中所示错误。这个错误牵扯到一个叫模的概念。下面是解释。

    1)模的概念:把一个计量单位称之为模或模数。例如,时钟是以12进制进行计数循环的,即以12为模。在时钟上,时针加上(正拨)12的整数位或减去(反拨)12的整数位,时针的位置不变。14点钟在舍去模12后,成为(下午)2点钟(14=14-12=2)。从0点出发逆时针拨10格即减去10小时,也可看成从0点出发顺时针拨2格(加上2小时),即2点(0-10=-10=-10+12=2)。因此,在模12的前提下,-10可映射为+2。由此可见,对于一个模数为12的循环系统来说,加2和减10的效果是一样的;因此,在以12为模的系统中,凡是减10的运算都可以用加2来代替,这就把减法问题转化成加法问题了(注:计算机的硬件结构中只有加法器,所以大部分的运算都必须最终转换为加法)。10和2对模12而言互为补数。
    同理,计算机的运算部件与寄存器都有一定字长的限制(假设字长为8),因此它的运算也是一种模运算。当计数器计满8位也就是256个数后会产生溢出,又从头开始计数。产生溢出的量就是计数器的模,显然,8位二进制数,它的模数为2^8=256。在计算中,两个互补的数称为“补码”。

    图3中 的错误解释:由于usigned long最大取值范围为2^32-1,而%d是以有符号整数进行输出,故进行了数值转换,即转为signed int,对于signed int 取值范围最大值小于usigned long,发生溢出,根据上述对模概念的说明,应该明白为什么输出是-2了。


    图3

    图4、图5为用基于X64处理器的gcc编译器输出各整型数据类型长度的结果


    图4

    图5


    展开全文
  • C语言整型数据类型

    2020-11-16 23:14:42
    1.1数据类型本质 数据类型本质就是固定内存大小... 数据类型划分以及其表示数据范围如下 长整型至少要和整型一样长,而整型至少应该和短整型一样长。 在实际开发过程中,short int 至少是16bit,而l...

    1.1数据类型的本质

    数据类型的本质就是固定内存大小的别名,因为每个数据类型编译器都规定了其占用内存空间的大小,在此基础上才衍生出了变量的大小,因此,变量的本质就是一段连续内存空间的别名。对变量的操作最终都是转换位对内存的操作。

    1.2整型的分类?

           整型分为字符,短整型,整型,长整型。同时有无符号和有符号之分。

         数据类型划分以及其表示数据范围如下

     

    1. 长整型至少要和整型一样长,而整型至少应该和短整型一样长。
    2. 在实际开发过程中,short int 至少是16bit的,而long int 至少是32bit的
    3. 在单片机开发种,一般无符号的数据类型,其定义方式如下所示。

    typedef unsigned          char u8;

    typedef unsigned short     int u16;

    typedef unsigned           int u32;

      4.在数值的后面添加L或者l,可以使这个数值被解释位long型,在后面添加U或者u,可以把数值指定为unsigned整型值,这在STM32的库中经常能看到该种表达方式。

    展开全文
  • 文章目录`limits.h` 的不足有符号整型的编码计算方法需要注意的地方以 int 传递 short取模位移 ...我们希望有一种方法,可以得到 C 语言中任意整型数据的取值范围。 根据编码的原理的不同,有符号类型和无符号类

    limits.h 的不足

    通过库 limits.h 中的常量,我们可以得知绝大多数整型的范围。但是其中并没有 long long 类型的取值范围。在 C++ 的库 climits 中定义了常量 LLONG_MIN, LLONG_MAX, ULLONG_MAX,但是这并不在 C 语言的范畴中。我们希望有一种方法,可以得到 C 语言中任意整型数据的取值范围。

    根据编码的原理的不同,有符号类型和无符号类型要分开讨论。我们先讨论有符号整型。

    有符号整型的编码

    假设用 nn 位(以下例子中 n=8n=8)来存储一个整数,用最高位作为符号位,那么这个整数的取值范围应当是 (2n1,2n1)(-2^{n-1},2^{n-1}) 考虑到00,实际取值范围是(2n1,2n11)(-2^{n-1},2^{n-1}-1)

    正数的编码就是其本身的二进制数,所以 2712^7-1的二进制数就是 01111111,而负数采用补码的方式存储,是其原码非符号位取反加一。例如 1-1 的原码为 10000001,反码为11111110,补码为 1111111

    27+1-2^7+1 的原码为 1111111,反码为 10000000,补码为 1000001。整数每-1,原码就+1,反码就-1,补码也-1。

    这样又体现了补码的好处。因为按照原码,2n12^{n-1} 是无法表示的,那么 2n1-2^{n-1} 也就无法表示。某种角度上说也是因为原码有 0-0,即就是 10000000 的存在。相应的反码也有这样的问题,因为在反码中 11111111 被 0-0 所使用,导致 27+1-2^7+1 就已经到了 1000000010000000。但是在补码中,我们有 10000001-1=10000000,用 10000000 来表示 27-2^7 就十分的平凡了。

    计算方法

    也就是说,8位整型的最小值为10000000,最大值为01111111。通过二进制运算 1<<7~(1<<7) 我们可以分别得到这两个数。

    将这种方法拓展,则有符号整型的最小值和最大值分别为 1<<sizeof(type) - 1,~(1<<sizeof(type) - 1)

    需要注意的是,有时 long 和 long long 的位数高于 int。我们不妨假设分别为16、32、64位。1 默认是一个 int 类型的数,在 1<<31 时会溢出而丢弃最高位,得到0的结果。所以我们应当使用 1L<<sizeof(long) - 11LL<<sizeof(long long) - 1 的方法。

    但是 C 总是充满了奇奇怪怪的特例。

    需要注意的地方

    以 int 传递 short

    首先要说的就是在传参的时候,short 类型会以 int 类型来传递。这可能是因为 int 往往是一个计算机的字长,具有更高的传输效率。例子如下:

    short int b = 1;	
    
    printf("%hd, %d\n", b<<16, b<<16);
    printf("%d, %lld\n", 1<<32, 1<<32);
    
    // 输出结果:
    // 0, 65536
    // 0, 0
    

    这是因为 b<<16 实际上是作为一个int被传输,就使得其并没有产生之前的溢出归零的问题。

    取模位移

    另一个特例是,如果变量向左移位多于存储位数,会对存储位数取模然后移位。但是常量和short不会。如下:

    short a = 1;
    int b = 1;
    long c = 1;
    long long d = 1;
    
    printf("%hd\n", a<<18);
    printf("%d, %d\n", 1<<34, b<<34);
    printf("%ld, %ld\n", 1L<<34, c<<34);
    printf("%lld, %lld\n", 1LL<<66, d<<66);	
    
    // 输出结果:
    // 0
    // 0, 4
    // 0, 4
    // 0, 4
    

    并且short不取模,不是因为它作为 printf() 的参数以int被传输,而是它真的不会取模。如下所示:

    short a = 1, aa = 3;
    
    aa = a<<18;
    
    printf("%hd, %hd\n", a<<18, aa);
    
    // 输出结果:
    // 0, 0
    
    展开全文
  • c语言整型与浮点型数据存取的范围

    千次阅读 2019-04-12 23:17:52
    c语言整型与浮点型数据存取的范围 整型数据: 1.long int 的由来 在win32及现在现在系统中,长度为4;在历史上,或者其他某些系统中,int长度为2,是short int。 所以: short<=int<=long 测试类型数据的字节...

    c语言整型与浮点型数据存取的范围

    整型数据:

    1.long int 的由来
    在win32及现在现在系统中,长度为4;在历史上,或者其他某些系统中,int长度为2,是short int。
    所以: short<=int<=long

    测试类型数据的字节数函数:sizeof(类型名称)

    printf("%d",sizeof(int));
    

    这里列举在win64下的类型字节数及取值范围

    类型名称 字节数 取值范围
    short (short int) 2 (-2 ^15)~ (2^15-1)-32768~+32767
    unsigned short 2 0~65535
    int 4 (-2 ^31)~ (2^31-1)-2147483648~ +2147483647
    unsigned int 4 0~4294967295
    long (long int) 4 (-2 ^31)~ (2^31-1) -2147483648~+2141483647
    unsigned long 4 0~4294967295
    long long (long long long int) 8 (-2 ^63)~ (2^63-1)-9223372036854775808~+9223372036854775807
    unsigned long long 8 0~18446744073709551615

    浮点型数据:

    取值范围(看指数部分):
    float的指数部分有 8bit (2^8),由于是有符号型,所以得到对应的指数范围-128~128。
    取值范围为:
    (-2 ^128)~ (2^128),约等于-3.4E38 ~ +3.4E38 ;
    double的指数部分有 11bit(2^11) , 对应的指数范围-1024~1024。
    取值范围为:
    (-2 ^1024)~ (2^1024),约 等于-1.797E308 ~ +1.797E308;

    精度( 有效数字)(主要看尾数位):
    float的尾数位是23bit,对应7~8位十进制数,所以有效数字有的编译器是7位,也有的是8位;
    double的尾数位是52bit,对应15~16位十进制数,有效数字位15位或16位。

    类型名称 指数位 尾数位 取值范围 有效数字
    float 8 23 (-2 ^128)~ (2^128) 约等于-3.4E38 ~ +3.4E38 7 或 8位
    double 11 52 (-2 ^1024)~ (2^1024) 约等于-1.797E308 ~ +1.797E308 15 或 16位

    double的存取的错误认知
    double类型可以存307位(实际是308,但存的最大的最高位为1,所以基本默认这里就讲307),
    但当用.f 输出double时, 它的精度在前16位,他只能保证前16位的精度,后面的就无法保证,因为一旦超过精度范围,就不能精确的描述该数据,不同的处理器对不能精确描述的部分的处理机制可能是不同的,这也就导致了在不同的平台上为什么一套代码的运行结果会不一致

    注意:
    printf()用%f输出double型,而scanf却用%lf
    严格地讲,%lf在printf下是未定义的,但是很多系统可能会接受它。
    要确保可移植性,就要坚持使用%f

    展开全文
  • C语言整型数据(整数)

    千次阅读 2015-01-13 18:30:41
    整型数据的分类 整型数据的一般分类如下: 基本型:类型说明符为int,在内存中占2个字节。 短整型:类型说明符为short int或short。所占字节和取值范围均与基本型相同。 长整型:类型说明符为long int或long,在...
  • C语言中16位整型数据的取值范围

    万次阅读 2019-08-21 17:16:37
    本文介绍C语言中16位整型数据的取值范围。 1. 无符号16位整型数据 对于无符号(unsigned)型数据,存储单元中全部二进位(bit)都用作存放数本身,而不包括符号。所以对于16位整型,取值范围如下: 0000 0000 ...
  • 本文介绍C语言中16位整型数据的取值范围。1. 无符号16位整型数据对于无符号(unsigned)型数据,存储单元中全部二进位(bit)都用作存放数本身,而不包括符号。所以对于16位整型,取值范围如下:0000 0000 0000 0000 到 ...
  • 本节讲解一下C语言的数据类型中的整型数据整型数据分为整型常量和整型变量两种, 1、我们先看一下整型常量,整型常量一共分为3种类型,10进制,8进制和16进制 2、接下来我们来看一下整型变量,首先来看一下整型...
  • 32位和64位机器整型数据类型典型取值范围 c语言的整型数据类型保证取值范围(有符号数范围对称) 来自《深入理解计算机系统》,参考深入理解计算机系统(2.3)
  • 系列文章目录 C语言系列课1:什么是计算机语言?... 整型数据类型2. 用sizeof关键词来测量大小3. 三位二进制表示数值范围4.数值补码表示法5.各种整型类型数值范围是多少6. 无符号整型7. char为什么叫字符型
  • 关于C语言整型数据的溢出

    千次阅读 2013-09-03 23:16:06
    #include int main() { int num1=32767,num2;  num2=num1+1; printf("%d,%d\n",num1,num2);...分析 有符号基本整型变量int的范围是-32 768~32 767即 -2^15~(2^15-1),在上例中num1=32 767,由于计
  • C语言整型数据类型

    千次阅读 2017-03-19 19:19:52
    1、整型数据的分类整型数据的一般分类如下:(以下说明的在内存中所占的字节数均是在vs2012这个开发工具里面的)基本型:类型说明符为int,在内存中占4个字节。短整型:类型说明符为short int或short。所占字节和...
  • 整型数在内存中的表示方法与取值范围 最近写程序,有人问我数据的取值范围,突然发现自己这些知识来自书本,只是记得和知道,等做细的时候... 整型数据的分类 短整型:short unsigned short[int] signed shor...
  • C语言的整型溢出问题 整数溢出 int、long int 、long long int 占用字节疑问 《C和指针》中写过:long与int:标准只规定long不小于int长度,int不小于short长度。 double与int类型存储机制不同,long int...
  • #include <... puts("该环境下各字符型、整型数值的范围"); printf("char: :%d~%d\n", CHAR_MIN, CHAR_MAX); printf("signed char :%d~%d\n", SCHAR_MIN, SCHAR_MAX); printf("unsignd char :%d~%d\n",
  • int型数据是一个有符号的整型数据,其最高位为符号位(0表示正,1表示负)。C++中,int占用4字节,32比特,数据范围为-2147483648~2147483647[-2^31~2^31-1]。详细解答过程,以两个字节为例:在C中,int型数据是一个有...
  • short整形在32位PC上是2个字节表示,每个字节是8个二进制比特,一共就是16个比特 16个比特,能表示个数是 0 ~ 2^16-1,即0 ~ 65535共65536个,如果表示正负整数各一半,那就是负整数-32768 ~ -1,共32768...
  • 在本文中,我们以短整型为例,给大家介绍该类型取值范围的计算方式,以及原理。首先默认情况下,unsigned int 占用2个字节(跟具体编译器和操作系统有关),也就是16位。在计算机存储的数据中,都是用0和1表示,...
  • C语言中,每种数据类型都有对应的取值范围,但是在不同的编译软件中,有些数据的取值范围是不同的。 在Windows32位编译机器上: 整型 [signed]int -2147483648~+2147483648 无符号整型unsigned[int] 0~4294967295 ...
  • 本篇博客将阐述、讨论的内容:●intint的范围根据计算机的不同存在16位或32位的差异,以16位举例,最大值为1111 1111 1111 1111,也就是65535,如果出现65536,就会溢出。●unsigned int(无符号整型)以16位系统为例...
  • 不同的整型使用不同内存量来储存整数,使用内存量越大, 可以表示整数值范围也越大。C++基本整型(按宽度递增顺序排列)分别是 char, short, int, long 和C++11新增 long long ,每种类型都分 有符号版本...
  • 数据类型:分为整形 , 浮点型整形: short int long longlong整型有无符号...无符号整型和有符号整型的区别就是无符号类型可以存放的正数范围比有符号整型的范围大一倍,因为有符号类型将最高位储存符号,而无...
  • C语言中常用数据类型有char(字符型),short(短整型数据类型),int(整形数据类型),long(长整形数据类型),double(双精度浮点型),float(浮点型)。  char在内存中是以一个字节8位储存,在内存中只有0或1,它...
  • 1、每种数据类型存储的数据是有范围的,故超出该范围数据会越限,造成数据错误。 例如: int类型,占用4个字节,其范围是从-2147483648~2147483647 (为何是此范围,详见...
  • C语言数据类型可容纳数值的范围c语言中,仅由4中基本数据类型----整形、浮点型、指针和聚合类型(如数组和结构等)。所有其他的类型都是从这4种基本类型的某种组合派生而来。首先让我们来介绍整形和浮点型。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 759
精华内容 303
关键字:

c语言整型数据的范围

c语言 订阅