mui 网站开发,深圳贝尔利网络技术有限公司,北京互联网公司排名,长春网络公司排名信息的表示和处理
寻址和字节顺序 位于0x100处#xff0c;int类型值0x01234567在大端和小端下的存储。 字符串的存储不受字节序影响。
移位
1.对左移#xff0c;右边统一补0 2.对右移#xff0c;分为算术右移#xff0c;逻辑右移 算术右移下#xff0c;左边补原最高有效…信息的表示和处理
寻址和字节顺序 位于0x100处int类型值0x01234567在大端和小端下的存储。 字符串的存储不受字节序影响。
移位
1.对左移右边统一补0 2.对右移分为算术右移逻辑右移 算术右移下左边补原最高有效位 逻辑右移下左边补0 默认对有符号数采用算术右移对无符号数采用逻辑右移。
无符号编码 x → [ x w − 1 , x w − 2 , . . . , x 0 ] \overrightarrow{x} [x_{w-1}, x_{w-2}, ... , x_0] x [xw−1,xw−2,...,x0] B 2 U w ( x → ) ∑ i 0 w − 1 ( x i ∗ 2 i ) B2U_{w}(\overrightarrow{x})\displaystyle\sum_{i0}^{w-1}(x_i*2^i) B2Uw(x )i0∑w−1(xi∗2i)
1.给定一个w个二进制数组组成的序列B2U_w是对此序列进行的一种解释解释的结果是将w个二进制数组成的序列映射为一个数值。 2.B2U_w将每个长度为w的位向量映射为 [ 0 , 2 w − 1 ] [0,2^w-1] [0,2w−1]中一个唯一的值。 U2B_w将每个 [ 0 , 2 w − 1 ] [0,2^w-1] [0,2w−1]中的值映射为一个唯一的长为w的位向量。
补码编码 x → [ x w − 1 , x w − 2 , . . . , x 0 ] \overrightarrow{x} [x_{w-1}, x_{w-2}, ... , x_0] x [xw−1,xw−2,...,x0] B 2 T w ( x → ) ∑ i 0 w − 2 ( x i ∗ 2 i ) − x w − 1 ∗ 2 w − 1 B2T_{w}(\overrightarrow{x})\displaystyle\sum_{i0}^{w-2}(x_i*2^i) - x_{w-1}*2^{w-1} B2Tw(x )i0∑w−2(xi∗2i)−xw−1∗2w−1
1.给定一个w个二进制数组组成的序列B2T_w是对此序列进行的一种解释解释的结果是将w个二进制数组成的序列映射为一个数值。 2.B2T_w将每个长度为w的位向量映射为 [ − 2 w − 1 , 2 w − 1 − 1 ] [-2^{w-1},2^{w-1}-1] [−2w−1,2w−1−1]中一个唯一的值。T2B_w将每个 [ − 2 w − 1 , 2 w − 1 − 1 ] [-2^{w-1},2^{w-1}-1] [−2w−1,2w−1−1]中的值映射为一个唯一的长为w的位向量。
3.补码的形象解释 有符号数在计算机中是以「补码」表示的对负数其补码就是把关联正数的二进制全部取反再加 1比如 -1 的二进制是把数字 1 的二进制取反后再加 1 4.为何有符号数采用补码表示 如果负数不是使用补码的方式表示则在做基本对加减法运算的时候还需要多一步操作来判断是否为负数如果为负数还得把加法反转成减法或者把减法反转成加法这就非常不好了毕竟加减法运算在计算机里是很常使用的所以为了性能考虑应该要尽量简化这个运算过程。
而用了补码的表示方式对于负数的加减法操作实际上是和正数加减法操作一样的。你可以看到下图用补码表示的负数在运算 -2 1 过程的时候其结果是正确的 采用补码表示下有符号数的加法可以采用简单的二进制位逐位相加的方式。补码减法也可变形为加法来操作。
类型转换
强制类型转换的结果保持二进制位不变只是改变对这些位解释的方式。
浮点数
1.十进制浮点数转换为二进制 最后把「整数部分 小数部分」结合在一起后其结果就是 1000.101。但是并不是所有小数都可以用二进制表示前面提到的 0.625 小数是一个特例刚好通过乘 2 取整法的方式完整的转换成二进制。
如果我们用相同的方式来把 0.1 转换成二进制过程如下 可以发现0.1 的二进制表示是无限循环的。 由于计算机的资源是有限的所以是没办法用二进制精确的表示 0.1只能用「近似值」来表示就是在有限的精度情况下最大化接近 0.1 的二进制数于是就会造成精度缺失的情况。
举个例子二进制 1010.101 转十进制的过程如下图 2.科学记数法与规格化 比如有个很大的十进制数 1230000我们可以也可以表示成 1.23 x 10^6这种方式就称为科学记数法。 该方法在小数点左边只有一个数字而且把这种整数部分没有前导 0 的数字称为规格化比如 1.0 x 10^(-9) 是规格化的科学记数法而 0.1 x 10^(-9) 和 10.0 x 10^(-9) 就不是了。
3.浮点数的二进制存储 如果二进制要用到科学记数法同时要规范化那么不仅要保证基数为 2还要保证小数点左侧只有 1 位而且必须为 1。 所以通常将 1000.101 这种二进制数规格化表示成 1.000101 x 2^3其中最为关键的是 000101 和 3 这两个东西它就可以包含了这个二进制小数的所有信息 (1).000101 称为尾数即小数点后面的数字 (2).3 称为指数指定了小数点在数据中的位置
现在绝大多数计算机使用的浮点数一般采用的是 IEEE 制定的国际标准这种标准形式如下图 这三个重要部分的意义如下 (1).符号位表示数字是正数还是负数为 0 表示正数为 1 表示负数 (2).指数位指定了小数点在数据中的位置指数可以是负数也可以是正数指数位的长度越长则数值的表达范围就越大 (3).尾数位小数点右侧的数字也就是小数部分比如二进制 1.0011 x 2^(-2)尾数部分就是 0011而且尾数的长度决定了这个数的精度因此如果要表示精度更高的小数则就要提高尾数位的长度
用 32 位来表示的浮点数则称为单精度浮点数也就是我们编程语言中的 float 变量而用 64 位来表示的浮点数称为双精度浮点数也就是 double 变量它们的结构如下 可以看到 (1).double 的尾数部分是 52 位float 的尾数部分是 23 位由于同时都带有一个固定隐含位这个后面会说所以 double 有 53 个二进制有效位float 有 24 个二进制有效位所以所以它们的精度在十进制中分别是 log10(2^53) 约等于 15.95 和 log10(2^24) 约等于 7.22 位因此 double 的有效数字是 15~16 位float 的有效数字是 7~8 位这些有效位是包含整数部分和小数部分 (2).double 的指数部分是 11 位而 float 的指数位是 8 位意味着 double 相比 float 能表示更大的数值范围
那二进制小数是如何转换成二进制浮点数的呢 我们就以 10.625 作为例子看看这个数字在 float 里是如何存储的。
首先我们计算出 10.625 的二进制小数为 1010.101。
然后把小数点移动到第一个有效数字后面即将 1010.101 右移 3 位成 1.010101右移 3 位就代表 3左移 3 位就是 -3。
float 中的「指数位」就跟这里移动的位数有关系把移动的位数再加上「偏移量」float 的话偏移量是 127相加后就是指数位的值了即指数位这 8 位存的是 10000010十进制 130因此你可以认为「指数位」相当于指明了小数点在数据中的位置。
1.010101 这个数的小数点右侧的数字就是 float 里的「尾数位」由于尾数位是 23 位则后面要补充 0所以最终尾数位存储的数字是 01010100000000000000000。
在算指数的时候你可能会有疑问为什么要加上偏移量呢
前面也提到指数可能是正数也可能是负数即指数是有符号的整数而有符号整数的计算是比无符号整数麻烦的所以为了减少不必要的麻烦在实际存储指数的时候需要把指数转换成无符号整数。
float 的指数部分是 8 位IEEE 标准规定单精度浮点的指数取值范围是 -126 ~ 127于是为了把指数转换成无符号整数就要加个偏移量比如 float 的指数偏移量是 127这样指数就不会出现负数了。
细心的朋友肯定发现移动后的小数点左侧的有效位即 1消失了它并没有存储到 float 里。
这是因为 IEEE 标准规定二进制浮点数的小数点左侧只能有 1 位并且还只能是 1既然这一位永远都是 1那就可以不用存起来了。
于是就让 23 位尾数只存储小数部分然后在计算时会自动把这个 1 加上这样就可以节约 1 位的空间尾数就能多存一位小数相应的精度就更高了一点。
那么对于我们在从 float 的二进制浮点数转换成十进制时要考虑到这个隐含的 1转换公式如下 举个例子我们把下图这个 float 的数据转换成十进制过程如下
4.浮点数精度0.1 0.2 0.3 ? 这两个结果相加就是 0.300000004470348358154296875 所以你会看到在计算机中 0.1 0.2 并不等于完整的 0.3。
这主要是因为有的小数无法可以用「完整」的二进制来表示所以计算机里只能采用近似数的方式来保存那两个近似数相加得到的必然也是一个近似数。
而我们二进制只能精准表达 2 除尽的数字 1/2, 1/4, 1/8但是对于 0.1(1/10) 和 0.2(1/5)在二进制中都无法精准表示时需要根据精度舍入。
我们人类熟悉的十进制运算系统可以精准表达 2 和 5 除尽的数字例如 1/2, 1/4, 1/5(0.2), 1/8, 1/10(0.1)。
当然十进制也有无法除尽的地方例如 1/3, 1/7也需要根据精度舍入。 当E中全部为二进制1时因为IEEE 标准规定单精度浮点的指数取值范围是 -126 ~ 127此时计算出来255 - 127 128超出范围了。所以此时 (1).当尾数部分部分不全为0时表示NaN。表示浮点数不存在。 (2).当尾数部分全为0时表示正无穷符号位为0或者负无穷符号位为1。
当E中全部为二进制0时因为IEEE 标准规定单精度浮点的指数取值范围是 -126 ~ 127此时计算出来0 - 127 -127超出范围了。所以此时 数值为 ( − 1 ) 符号位 ∗ ( 0 尾数位 ) ∗ 2 − 127 (-1)^{符号位}*(0尾数位)*2^{-127} (−1)符号位∗(0尾数位)∗2−127
1.从int转成float数字不会溢出但可能被舍入。 2.从int或float转成double可保留精确数值 3.从double换成float可能溢出为正无穷负无穷。可能被舍入。 4.从float或double转成int可能会溢出。值将向0舍入。 溢出体现在超出表示范围舍入体现在稠密映射到稀疏下无法精确的一一映射但可映射到最接近的。