zoukankan      html  css  js  c++  java
  • 走进计算机的世界---漫谈计算机数据存储的宽度

    数学上的数字,是没有限制的,可以无限大,而在计算机中,受硬件的制约,数据是有长度的(即每个数据最多可以有几个二进制位),称为数据宽度,超过最大宽度的数据将会丢失一部分。我们知道计算机数据表示只能有0,1两个数字,称为二进制,那么在程序编程语言中,我们一般划分数据宽度为三种:

    BYTE 字节 8 bit

    WORD 16bit  =2字节

    DWORD 双字 32bit 双字=2=4字节

    C语言为例,char 数据宽度为byteshort 数据宽度为wordint数据宽度为dword

    我们分析一下在计算机中数据宽度是如何理解的。

    下面我们逐一分析

    4位宽度为例,假设计算机只能存储4个二进制位。2^4=16,可以存储16个数字,

    0000 0001  0010  0011  0100  0101  0110  0111  1000  1001  1010  1011  1100

     

    1101  1110  1111

     

    若这16个数

    全是无符号数:

    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F

    全是有符号数:

    正数: 0   1   2   3   4   5   6   7

    负数: -1   -2   -3   -4   -5   -6   -7   -8

                       F   E    D   C    B   A   9     8

    由上面分析,我们可以看出,计算机中存储的只是若干位的二进制数,计算机并不区分正负数,正负数是编程人员规定的。从示意图可以看出,F为最大负数,因为F再进一位就为0,所以F 是最大的负数,而且从有符号数说起,纵轴左边是负数,最高位为符号位,最高位为1就是负数,为0就是正数。这也可以理解计算机中存储负数,即存储该数绝对值的补码,然后最高位变为1 ,即可。

    切记,计算机并不决定数是正数还是负数,正负性是由编程人员决定的,从原理上看,无论整数还是负数,在计算机中表示的二进制字符串都相同,由编程人员来确定正负。

    比如 8位的二进制数 10000000,若为无符号数,则是128,若是有符号数,则是-128,由此可见,正负性是由编程人员决定的。

     

    同理以8位宽度为例,即以字节byte为例,可以得到示意图,4位二进制用16进制表示

    无符号数:

    0   1   2   3   … FF(10进制为255)

    有符号数:

    正数: 0   1   2   … 7F(10进制127)

    负数: -1    -2   -3 …  -128

    FF   FE   FD  …   80

     

    同理 16位宽度,假设计算机只能存储16位二进制位

    无符号数:

    0   1   2   3   … FFFF(10进制为2^16-1)

    有符号数:

    正数: 0   1   2   … 7FFF(10进制127)

    负数: -1      -2     -3       -4   …

    FFFF   FFFE   FFFD    FFFC  …

    同理 32位宽度,不在此罗列了

    总结:

    从计算机角度看,它不知道什么叫有符号数,什么叫无符号数,什么是正数,什么是负数,只管存储二进制数,但是从使用者角度看,计算机中每个数据都是一个容器,有自己最大的宽度,可以决定是否有无符号(从而数据宽度也不同),一旦超过宽度,将会使得最高位数据被丢失

             学以致用:

    分析下面C语言程序,写出程序运行结果(此题摘自程正冲的C语言深度剖析)

    Int  main()

    {

             char a[1000];

             int i;

             for(i=0;i<1000;i++)

             {

                       a[i]=-1-I;

             }

             printf(“%d”,strlen(a));

    return 0;

    }

    思路:越是简单题越容易出错,很多同学看到strlen函数,哦求字符串长度,直接写个1000,

    而有的同学可能会进一步思考,求字符串长度函数的本质是什么,是遇到第一个数字0的时候就输出长度,可是困惑字符数组a的哪个下标存储数组0。这里就要用到我们刚才所讲的数据宽度问题。因为数组a为字符型,宽度为一个byte,而分析for循环可知,

    a[0]=-1,计算机存储的是0xff,

    a[1]=-2,计算机存储0xfe,

    a[127]=-128,是char类型所能存储的最小负数0x80。

    当i在增1 时,a[128]的值肯定不是-129,因为一个byte字节能存储的有符号数为-128~ ~127,因此会发生下溢,最高位被丢弃,剩下的8位是0111  1111 ,即0x7f,(原因如下

    (1000 0000)-(0000 0001)=(0111 1111),向第九位借了一位

    I继续增大,直到a[254]=0x1,a[255]=0x0,

    然后a[256]=0xff,又开始循环,但是a[255]=0即0000 0000,因此可以肯定a[0]到a[254]都不为0,而a[255]为0,所以strlen(a)长度是255.

    解法二:如果是选择题,也可以简略思考答案,首先依据示意图无符号数(范围从0到255共256个数)就可以得出,从a[0]=0xff,一直减1,就是绕示意圆顺时针转,一直转到a[255]=0x00,所以strlen(a)长度为255.

  • 相关阅读:
    (五)STL序列容器(deque)
    (四)STL序列容器(vector)
    (三)STL序列容器(array)
    (六)c语言之指针与函数、数组用法
    (五)c语言之内存分配
    (三)c++模板函数与函数模板详解
    Linux基础(03)gdb调试
    Linux基础(02)MakeFile的创建和使用
    Linux基础(01)开发环境的搭建
    Windows的socket编程
  • 原文地址:https://www.cnblogs.com/gaochaochao/p/8485297.html
Copyright © 2011-2022 走看看