代码改变世界

C语言数据类型取值范围

2016-11-09 15:59  ZengGW  阅读(4004)  评论(0编辑  收藏  举报

一、获取数据类型在系统中的位数

  在不同的系统中,数据类型的字节数(bytes)不同,位数(bits)也有所不同,那么对应的取值范围也就有了很大的不同,那我们怎么知道你当前的系统中C语言的某个数据类型的字节数,位数呢?

  由于本人是初学,所以下面的代码是硬编程了,获取一个数据类型的字节数和位数:

/* 获取数据类型在当前系统中的字节数(bytes)和位数(bits) */
#include <stdio.h>
int main(void)
{
        //1个字节 = 8位
        printf("整数类型:int;bytes = %d;bits = %d\n",sizeof(int),sizeof(int) * 8);
        return 0;
}

  上面的代码中使用的函数sizeof来获取数据类型对应的字节数,对应的位数也就出来了,那么很多时候在编程的时候,要是我们不知道数据类型在本系统中的位数和取值范围的话,很容易出现问题:数据类型的值向上溢出,或者向下溢出了,而我们还不知到怎么回事,这个时候找问题就很费劲了

二、获取整数数据类型对应的取值范围

  首先来举个例子:

    数据类型:char(字符串,实际以整数存储) 

    字节数:不管在哪个操作系统中都是1个字节

    位数:1个字节 = 8位(以二进制存储)

    无符号取值范围:00000000 ~ 11111111 (有8位二进制数存储),那么结果char的取值范围是0~255

    有符号取值范围:-2^7 ~ (2^7)-1 也就是-128 ~ 127

  那可能你会问了,为什么计算有符号的取值范围时,最后需要减1呢?请看下面的分析:

    有符号取值范围分正数:127 =(转换成二进制)=>1111111(这里二进制只有7位,换句话说,实际二进制值是01111111)

    有符号取值范围分负数:-128 =(转换成二进制)=>10000000(刚好是8位)

  不知道大家有没有发现他们的区别?

  区别(update 2016-11-10 感觉这个最高位区分正负数很矛盾啊!有待验证):

    正数:二进制的最高位是0,最高位是0表示正数

    负数:二进制的最高位是1,最高位是1表示负数

  引申一个问题:怎么区分一个二进制数的正负呢?如何区分二进制补码还是原码????

  也就是说二进制也有正数和负数的区别(讲个插曲,之前我学进制转换的时候做练习题,看到有负数,我当时就干蒙了,现在才明白是这么区分的)

  同样的,其他的数据类型都是这么计算的,下面总结一下计算公式,方便快速计算数据类型的取值范围:

    下面的bits = 数据类型的字节数 * 8;

    signed typeName(有符号的数据类型取值范围):-2^(bits-1) ~ (2^(bits-1))-1

    unsigned typeName(无符号的数据类型取值范围):(2^bits)-1

三、浮点数的取值范围

  暂时我不知道怎么计算,使用的是c的函数库来获取的

#include <stdio.h>
#include <float.h>
int main(void)
{
        printf("%e\t%e\n",FLT_MIN,FLT_MAX);
        return 0;
}

  引用函数库float.h ,使用FLT_MINFLT_MAX获取浮点数的取值范围

  本人初学,有错误欢迎指出来,大家共同进步!