欢迎光临散文网 会员登陆 & 注册

C/C++ 从入门到入门 3 数据类型(非编程语言向)

2023-02-23 14:06 作者:确实挺难受  | 我要投稿

问个不是问题的问题, 为什么要有数据类型......

再问个问题, 为什么北方冬天外出要穿羽绒服......

一切都指向一个答案 

--> 我需要 <--

说了等于没说.

计算机数据类型的存在原因是, 现实世界中有很多不同类型的数据, 计算机无法直接区分, 所以需要利用不同的编码格式以及运算规则, 使计算机存储并且使用这些数据.

鸽了几个月, 今天接着说

我们先不从C / C++ 中的数据类型表示方式说起. 我们先扯点别的.

在计算机中, 所有数据都是用二进制的方式存储的. (啊除非你说的是贴在主板或者某芯片上的标签上的信息) 同样的二进制数据, 在没有任何其他的辅助方案的情况下, 只有一种表示方式. 那就是纯纯的二进制. 

所以, 人们在数制的基础上, 搞出了数码的概念. 本文将针对常见的整数和浮点数的编码方式进行说明, 让各位较为直观的了解到不同类型数据表达格式的不同.

整数

整数常用的有四种表示方法, 分别是 原码 反码 补码 移码.

根据UP所学, 给出解释. 以下表示方式, 约定 6 位二进制 编码, 其中符号位占一位

原码

将二进制表示方式中的 + - 符号, 以 s 表示, 其中 s 是  (-1)%5Es, 在二进制中, 1 表示为 负数, 0 表示为整数, s 所在的位称为 符号位, s 就是 数符. 

e.g. 表示 5, -5

5_%7B(10)%7D%20%3D%20101_%7B(2)%7D%20%3D%2000%5C%200101_%7B(%E5%8E%9F)%7D%5C%5C%0A-5_%7B(10)%7D%20%3D%20-101_%7B(2)%7D%20%3D%2010%5C%200101_%7B(%E5%8E%9F)%7D%0A

相对于纯二进制, 原码将符号数字化了.

反码

正数反码和原码完全相同, 不再说明.

针对负数. 反码保持符号位不动, 将所有的数值位按位取反(0, 1互换).

e.g. 表示 5, -5

5_%7B(10)%7D%20%3D%20101_%7B(2)%7D%20%3D%2000%5C%200101_%7B(%E5%8E%9F%2C%20%E5%8F%8D)%7D%5C%5C%0A-5_%7B(10)%7D%20%3D%20-101_%7B(2)%7D%20%3D%2010%5C%200101_%7B(%E5%8E%9F)%7D%20%3D%2011%5C%201010_%7B(%E5%8F%8D)%7D%0A

将原码的数值位全部取反操作

补码

正数的补码和原码完全相同, 不再说明

针对负数, 补码在反码的基础上, 结果做 + 1 操作.

e.g. 表示 5, -5 

5_%7B(10)%7D%20%3D%20101_%7B(2)%7D%20%3D%2000%5C%200101_%7B(%E5%8E%9F%2C%20%E5%8F%8D)%7D%5C%5C%0A-5_%7B(10)%7D%20%3D%20-101_%7B(2)%7D%20%3D%2010%5C%200101_%7B(%E5%8E%9F)%7D%20%3D%2011%5C%201010_%7B(%E5%8F%8D)%7D%20%3D%2011%201011_%7B(%E8%A1%A5)%7D%0A

补码回到原码的操作也是除符号位以外按位取反再加一

移码

隔路的一种编码, 常见的是数值位和补码完全相同, 符号位和补码完全相反.

C 语言中, 带符号数, 都是采用补码的方式进行存储. 原因在于, 计算机计算加法操作, 比计算减法操作容易很多, 所以将减法操作, 转换成为了加相反数的操作., 如何让加相反数也能方便表示? 我们通过思考钟表的调整考虑. 

现在钟表指向 8 位置, 现在向后调整时间的旋钮坏了. 只能向前调整, 问调整几个小时, 能调整到 4 的位置?

答案是 8 个小时

将相同的思想迁移到二进制中, 补码的意义就在于此.

e.g. 计算 5-7 

5_%7B(10)%7D%20%3D%20101_%7B(2)%7D%3D%2000%5C%20101_%7B(%E5%8E%9F%2C%20%E8%A1%A5)%7D%5C%5C%0A-7_%7B(10)%7D%20%3D%20-111_%7B(2)%7D%20%3D%2010%5C%20111_%7B(%E5%8E%9F)%7D%20%3D%2011%5C%20000_%7B(%E5%8F%8D)%7D%20%3D%2011%5C%20001_%7B(%E8%A1%A5)%7D

11110_%7B(%E8%A1%A5)%7D%20%3D%2010010_%7B(%E5%8E%9F)%7D%20%3D%20-10_%7B(2)%7D%20%3D%20-2

将减法转换为加法, 是计算复杂程度降低. 就是补码的存在意义.

以上是关于整数在计算机中的表达方式.

浮点数

浮点数是和定点数相对. 所谓定点数, 就是制定了小数点位置的数.

在电脑中,定点数(英语:fixed-point number)是指用固定整数字数表达分数的格式,属于实数数据类型中一种。例如美元常会表示到二位小数,以分来表示,即为一种定点数。有时定点数也会要求要有固定的整数字数。定点数与更复杂的浮点数相对。

在定点数表示法中,小数部分和整数部分一样,也会表示为进制底数b的幂次,不过是以负数幂次来表示。最常见的定点数表示法是十进制(底数为10)和二进制(底数为2)。若存储了n位的小数,其数值一定是b−n的整数倍。定点数表示法也会用来省略整数中较低位数的值,例如将金钱表示为1000美元的整数倍。

在人们处理有小数的十进制数字时,会在整数和小数之间加上小数点('.'或是',')。不过定点数中,整数和小数的位数长度是依程序的规划来决定。

--摘自 维基百科 定点数介绍

当然, 以上内容, 由于出现的频率很少, 且在程序设计中很少涉及, 所以不做过多介绍, 浮点数在C / C++语言中的常用两种表达方式是 float 和 double 分别代表 32 位浮点数和 64 位浮点数. 浮点数在计算机中的表示方式按照下面的公式分成三个部分:

(-1)%5ES%20%5Ctimes%202%5EE%20%5Ctimes%20M%20 

S%20%5Ctext%7B%E7%A7%B0%E4%B8%BA%E6%95%B0%E7%AC%A6%2C%20%7DE%20%5Ctext%7B%20%E7%A7%B0%E4%B8%BA%E9%98%B6%E7%A0%81%2C%20%7D%20M%20%5Ctext%7B%20%E7%A7%B0%E4%B8%BA%E5%B0%BE%E6%95%B0%7D

其中数符占1位表示正负, 针对不同种类的浮点类型数据, 有不同种类的阶码长度要求和尾数长度要求.

32 位浮点数

阶码 E 占 8 位, 采用移码编码, 8位二进制可以表示的正整数范围是0~255,  分出一半来表示 128~255和-127~0, 阶码设计上不想出现判断数符的情况, 将所有的阶码为负数的部分移动到整数, 所以偏置值是127. 即, 如果真值是-1 在阶码表示中, 应该写成是127-1 = 126的二进制表示方式

尾数 M 占剩余的23位, 表示为科学记数法中的数值部分, 严格按照科学记数法处理.

比如 1010.01111, 应该先转换成1.01001111再填入尾数部分. IEEE考虑到, 以0为整数部分时, 会有至少1位的内容无法精确表达出来, 所以要求, 尾数部分 M = 1.m. 填入小数点后面的 m 部分缺位右侧补零. 这个操作, 行话叫"规格化".

e.g. 没有规格化的 0.m ; 规格化的1.m;

比如定点数 0.00000111 应该转换成 1.11, 并且调整相应的阶码值再将小数点后面的部分填入尾数区域.

32位浮点数IEEE格式要求

64 位浮点数

阶码  11 为, 采用移码编码.11位. 11位2进制可以表达的整数范围是0~2047, 分一半表示 -1023~0 和 1~1024. 即用 表现值0 表示真值 -1023. 故其偏置值为 1023. 阶码真值是 -1 的需要加1023 变成阶码表现值1022 转化为2进制填入阶码区域中. 

尾数 占 52 位, 填入规则和32位浮点数基本相同. 同样, 需要规格化处理.

64 位 浮点数 IEEE 格式要求

由于最终结果太长, 于是从右侧开始, 每四位一组, 将结果用16进制表示.

总结

数据在存储之前会用特定的编码方式进行编码, 在存储时, 计算机根据数据类型或者是根据数据本身的长度, 将数据保存到内存空间中, 如果需要, 将其进行命名操作. 这样得到的东西, 就是变量. 不同的数据表达的方式不同, 所以会有数据类型的存在.

以上操作, 在C / C++ 内部进行处理, 外部需要提供的是这个变量存储的数据类型. 即可.

下一篇将针对C / C++ 描述几种基本的数据类型以及他们的书写方式, 包括相关关键字等内容.

感谢各位的支持 !


C/C++ 从入门到入门 3 数据类型(非编程语言向)的评论 (共 条)

分享到微博请遵守国家法律