博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
计算机数值表示
阅读量:5144 次
发布时间:2019-06-13

本文共 1832 字,大约阅读时间需要 6 分钟。

 

一、概述

       近几日觉得理解计算机的数值表示对实际编程的理解有帮助,于是就回忆整理了以前的学的基础知识,主要来自《计算机原理》与《深入理解计算机系统》,本文讨论计算机整数表示与小数的定点法表示与十进制的映射.

二、整数

       我们表达一个数都是用K进制数的方式,K进制数是一个指数,无符号模式的任i位上的数都可以表示为Ki*Ki-1。计算机是用二进制表示数的,因此它位上的通项公式为2i*2i-1。整数分为无符号与有符号两种,下面分别来讨论.

1、无符号整数

            二进制的无符号整数与十进制的映射,直接用2i*2i-1对每一位进行求和即可。定义一个映射函数为(数学符号不会打,因此用手写的表示):

           

        其值域为[0,2w-1].

2、有符号整数

       计算机表示有符号整数通常有三种编码方式:原码、反码、补码。但一般用补码,因此下面主要讨论补码.

2.1、原码

       所谓原码,就是指最高位充当符号位,不充当实际计数。定义一个映射函数为:

      

       其最小值就是B2Uw-2取最大值,最高位为1时,为-2w-1+1,最大值就是B2Uw-2取最大值,最高位为0时,为2w-1-1,因此其值域为[-2w-1+1,2w-1-1].

2.2、反码

        所谓反码,就是最高位充当权-(2w-1-1)参与计数。定义一个映射函数为:

       

        其最小值就是B2Uw-2取0时,最高位取1时,为-2w-1+1,最大值就是B2Uw-2取最大值,最高位取0,为2w-1-1.因此其值域为[-2w-1+1,2w-1-1].

2.3、补码

        我们从原码和反码的值域可以看出,它们的负域与正域都是对称,也就是能表示2w种状态,也就是有正0与负0,因此不够完美。在某一天,一个聪明的印度人发明了补码,完美的表示了有符号整数.

        所谓补码,就是最高位充当权-2w-1参与计数。定义一个映射函数为:

       

        其最小值为B2Uw-2取0时,最高位取1时,为-2w-1,最大值为B2Uw-2取最大值,最高位取0时,为2w-1-1,因此其值域为[-2w-1,2w-1-1].从值域可以看出,负域比正域多1,从而完美表示2w-1钟状态.

2.4、根据x求-x的补码

        我们设B2Tw=-x,替换并左右移动可以得B2Uw-2=2w-1-x,从这可以看出-x的0到w-2位的无符号形式为2w-1-x,我们再把最高位权算进来得2*2w-1-x,也就是2w-x,欧,我们换种写法来看看:2w-1-x+1,等于什么意思?就是取反再加1.因此根据x的补码求-x的补码就是2w-x的无符号形式,也就是对x的进行取反加1操作.

2.5、有符号补码转无符号形式.

        从B2Tw与B2Uw的对比可以看出,其差别就是前者多减了一个2w-1,少加了一个2w-1,因此只要补回来就行了,为x+2*2w-1=x+2w。反之,B2Uw------>B2Tw只要减两个2w-1就行了,为x-2w.

三、定点小数

         所谓定点小数就是由程序员约定小数点在数的那一位,计算机不存储小数点的位置,也就是说将小数转为整数来存储,来运算,可以优化运算的性能(整数运算要比浮点快).

1、小数与定点小数互转

         我们在日常手动计算时,常常通过将小数点右移将小数转为整数,算完再小数点左移相等的位置,也就是乘或除10n(n表示移动的位数),如0.25右移两位=0.25*102=25,25左移两位=25/102=0.25。右移也就表示保留几位小数.在计算机中只不过把10换为2罢了.但是二进制的右移并不总得一个整数,有余数时需要四舍五入,因此定点小数是有精度损失的,不过保留的小数越多,精度也就越高。我们定义小数为f,保留几位小数的定点小数为Qn,综上所述得:

        Qn=f*2n

        f=Qn/2n;  C语言表示:int q=819;int n=1<<12;float f=(float)q/n;

2、定点小数运算

      我们知道小数加减,小数点是不会变化的,因此定点小数的加减法与整数一样.而两个小数乘除法小数是会发生移动的,如0.2*0.3=0.06,1.25/0.5=2.5,而一个整数乘以一个小数,一个小数除以一个整数时小数点位不会发生移动。因此:

       qn=f+f2=q1n+q2n;

       qn=f-f2=q1n-q2n;

       qn=f*f2=q1n*q2n/2n;   q2n/2n把q2n转为f2

       qn=f/f2=q1n*2n/q2n; 

       

           

           

 

转载于:https://www.cnblogs.com/yshuihan/p/4279631.html

你可能感兴趣的文章
gzip
查看>>
转负二进制(个人模版)
查看>>
LintCode-Backpack
查看>>
查询数据库锁
查看>>
我对于脚本程序的理解——百度轻应用有感
查看>>
面试时被问到的问题
查看>>
当前记录已被另一个用户锁定
查看>>
Node.js 连接 MySQL
查看>>
那些年,那些书
查看>>
注解小结
查看>>
java代码编译与C/C++代码编译的区别
查看>>
Bitmap 算法
查看>>
转载 C#文件中GetCommandLineArgs()
查看>>
list control控件的一些操作
查看>>
绝望的第四周作业
查看>>
一月流水账
查看>>
npm 常用指令
查看>>
判断字符串在字符串中
查看>>
Linux环境下Redis安装和常见问题的解决
查看>>
HashPump用法
查看>>