Loading [MathJax]/jax/output/HTML-CSS/jax.js

C/C++ 语法教程(2)——数据存储与进制转换

C/C++ 语法教程(2)——数据存储与进制转换

Contents [hide]

数据存储与进制转换

数据存储

众所周知,计算机中都是以二进制存储数据,但是不同的类型有很多种不同的存储要求,所以存储格式也各不相同。

无符号整型

存储即为其二进制,比如 8 位二进制数 01101011 表示的就是十进制数 107

故如果输入数据超过存储上限(也称为溢出),相当于对 2位数 取模。

有符号整型

与无符号整型的最大区别就是最高位(左数第一位)变成了符号位,0 表示正数,1 表示负数。

正数的后面若干位就是按二进制(也称为原码)存储,而负数则是按补码存储(反码 +1),所谓反码就是将除符号位的所有位取反(0110)。

比如 18 位原码是 10000001,反码就是 11111110,补码就是 11111111

特别地,10000000 本来表示 0,但实际用于表示 128。(位数增加也同理)

而有符号整型的溢出相当于无符号型的大的那一半接到了负数这边,比如 8 位时,10000000 表示有符号整型的 128,也表示无符号整型的 12811111111 表示有符号整型的 1,也表示无符号整型的 255

浮点型

浮点型的存储大概分为符号位、尾数和阶码(反正名字不用记住)。

符号位 s=0/1 代表正数或者负数((1)s)。

尾数 M 是一个二进制小数,与科学计数法相似,可以认为是二进制的科学计数法,也就是说 1M<2。阶码 E 代表 2 的幂,跟科学计数法相似,但其存储方法与有符号整型也不同。最后浮点型的数值表示为 V=(1)s×M×2E。如果是单精度浮点数,也就是 32 位二进制,一般开头 1 位表示符号位,中间 8 位表示阶码,最后 23 位表示尾数(注意顺序跟前面不同)。如果是双精度浮点数,则是 1+11+52 的模式。尾数部分因为小数点前的一位必定是 1,所以不存储,只保存小数点后面的若干位。阶码先换算成二进制,然后整体平移,大概就是比如单精度 8 位存储,就是加上 127 再存储,也就是说 4 实际存储为 131。特别地,当 E 全为 0 时,用于表示 0 或者特别接近 0 的数;当 E 全为 1 时,且 M 全为 0,用于表示(正负)无穷大;当 E 全为 1 时,但 M 不全为 0,用于表示不是一个数(NaN),常见于被零(整型)除,负数开放等错误操作。

进制转换

q 进制转成十进制

初始为 0,不断地乘 q 加上这一位的数,记得到其十进制。

十进制转成 q 进制

不断除 q,然后余数从前到后即为 q 进制的位从低到高。(应该都好懂)

特殊的进制转换

比如二进制与十六进制,就可以将二进制按 4 位分组,然后对应十六进制的一位。

C/C++ 中的进制转换

printf("%05o\n",35);    //按八进制格式输出,保留5位高位补零
printf("%03d\n",35);    //按十进制格式输出,保留3位高位补零
printf("%05x\n",35);    //按十六进制格式输出,保留5位高位补零
C++
#include <bitset>
#include<iostream>
using namespace std;
int main()
{
    cout << "35的8进制:" << std::oct << 35<< endl;
    cout << "35的10进制:" << std::dec << 35 << endl;
    cout << "35的16进制:" << std::hex << 35 << endl;
    cout << "35的2进制: " << bitset<8>(35) << endl;      //<8>:表示保留8位输出
    return 0;
}
C++

除此之外还有 itoa 函数,大家可以自行研究。

 

点赞 0

No Comments

Add your comment

Per aspera ad astra.