哈喽大家好,我是TianshiyuMogui,距离我们上一期已经有段时间没更新了,最近太难了。这期内容带大家了解什么是定点数/浮点数,废话不多说开始。
都知道计算机数值是以二进制补码形式进行存储,那么问题来了,数值中除了整数外还有小数存在,那么小数点在计算机中是如何表示的呢?
小数的小数点在计算机中有两种表达方式; 一种是约定数值的小数点隐含在某一个固定位置上(定点数)表示数值范围小; 另一种则是小数点的位置可以浮动(浮点数)表示数值范围大; 定点数/浮点数是为了解决小数点的问题。1.定点数
概念:顾名思义就是小数点是固定的,约定数值的小数点隐含在某一个固定位置上;、
小数点固定在机器数的最低位(定点整数)小数点固定在符号位后面(定点小数)
所以定点数分为:定点(纯)整数、定点(纯)小数。
表示格式
定点整数/小数表示格式
- 定点整数
格式:符号位=数值部分(尾数) .小数点
涉及有符号数和无符号数,原码、反码和补码这些内容在我们上一期内容有讲到,那么我们再来讲讲有/无符号数吧!
有符号数:最高为代表符号位(0代表正、1代表负)其余代表数值
例如:1111=-7
无符号数:所有数都代表数值,没有符号位,它没有负数。
例如:1111=15
- 定点整数数值表示/数值范围
整数数值表示/数值范围
- 定点小数
定点小数数值表示/表示范围:
定点数数值表示/表示范围
( 其中x0为符号位,x1~xn是数值的有效部分,也称为尾数, x1为最高有效位 )
位数是定长的,所以表示的值是有限的,运算结果超出表示范围就是溢出
定点数溢出的判定
数值判定,如果计算机的机器子长为4,那么能够表示的真值范围在-8---+7之间,如果两个数相减,跳出了这个范围,则为溢出。
次高位向最高为进位异或(⊕)、最高位向进位位进位的方法来判定,其值位1,表示溢出,
用双符号来判定。
小数定点数中的数,其绝对值必须小于1,否则“溢出”,此时要求机器停止运算,进行处理。
定点数表示数值有限,所以表示比较大的数时我们用浮点数来表示(范围大)
2.浮点数
概念:顾名思义浮点数,就是小数点的位置可以任意浮动
百度定义是:浮点数,是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数 。具体的说,这个实数由一个整数或定点数(即 尾数 )乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的 科学计数法。
图片来源于网络
浮点数分为两种表示形式:一种是一般格式(也是百度常见的) 另一种是IEEE754标准格式
一般格式如图
浮点数一般表示格式
阶码就是指数;阶符就是指数的符号;数符是指尾数的符号,它们各占多少位取决于表示范围,表示精度等方面的权衡。比如32位长的浮点数,阶符和阶符各用1位,阶码可以用7位,尾数23位;阶符和阶码也可以结合起来,用一个8位来表达,一般格式中将数符放在中间部分,这与定点表示格式不一致,而且在计算机处理时也不够方便,因此实际中一般采用IEEE754来表示格式,如下。
图片来源于网络
IEEE754格式
符号:(正 0 负1)
有效数 S(significant)
指数 E(exponent)
- 基数 B(二进制的基数等于2)隐含的不用存储,因为它对所有数值都是相同的
浮点数IEEE754标准格式
最左位保存数的符号(0=正,1=负(符号位));
指数值存于位1到位8,所用的表示法称为偏移表示法;
最后一部分是有效数(尾数)。此例的基值被认为是2;
如果不对浮点数的表示作出规定,同一个浮点数的表示就不是唯一的,为了提高数据的表示精度,当尾数不为0的时,其绝对值规定0.5≤S<1,即尾数的最高有效位应为1,否则要以修改阶码同时左右移小数点的方法,使其变成符合这一要求的表示形式,这称为浮点数的规格化处理,这样也为了节省空间。由于尾数最高有效位为1,可左移后不代表不占位,可使尾数无形中增加一位,从而增加了尾数精度。指数规定用偏移表示法,即在补码的基础上加上128,相当于补码的符号位取反,称为移码最大值为全1,最小值为全0;偏移指数的值为±2^E-128。
浮点数规格化
浮点数都是近似表示的,精度由尾数决定,数的表示范围大小由R、E决定,为了提高精度需要使尾数的有效位数尽可能占满可用的位数,这种称为浮点数的规格化。
规格化要求尾数:
1/R<=|M|<1
R=2时 0.5<=|M|<1
即2^-1<=|M|<2^0
)2↓<=|M|<(1)▼2
右规:尾数右移一位,阶码+1
左移:尾数左移一位,阶码-1
对于规格化浮点数小数点后第一个值时固定的(正数:1,负数:原码1、补码0)
所以该位往往缺省,称为隐藏位。
规格化处理,若得到的结果不满足规格化规则,就必须把它变成规格化的数,对双符号位的补码尾数来说,就必须时001XX....X或110XX...X的形式。
当结果尾数的两个符号位的值不同时,表明尾数运算结果溢出。此时应使结果尾数右移一位,并使阶码的值加1,这被称为向右规格化,简称右规。
当尾数的运算结果不溢出,但u子高数值位于符号位同值,表明不满足规格化规则,此时应重复地使尾数左移、阶减减1,直到出现在最高数值位上的值与符号位的值不同为止,这是向左规格化的操作,简称左规。
有规格化同样也有非规格化这里给出别文作者大家一起学习:
浮点数表示范围:https://blog.csdn.net/qq_36636525/article/details/80775747
图片来源于网络
如果一个浮点数的尾数为0,不论其阶码为何值,或者阶码的值为0(实际值我为-128),不管其尾数为何值,计算机都把该浮点数堪称零值,称为机器零。
假设由S、E、M三个域组成的一个32位二进制字所表示的非规格化浮点数X,其真值表示为
X=±S*B^±E=(-1)^s*(1,M)*2^E-128
问:它所表示的规格化的最大正数,最小正数,最大负数,最小负数是什么?
如图解答:
解析
浮点数的溢出,若指数E>127,无论正负,均为绝对值大于可以表示的范围,称为”上溢“;若指数E=0,无论正负,均为绝对值小于可表示的范围,称“下溢”。为“下溢”即可堪称是机器零。
浮点数的溢出是以其阶码溢出表现出来的。在加\减运算过程中要检查是否产生了溢出:若阶码正常,加(减)运算正常结束;若阶码溢出,则要进行相应处理。另外对尾数的溢出也需要处理。
阶码上溢 超过了阶码可能表示的最大值的正指数值,一般将其认为是+∞和-∞。
阶码下溢 超过了阶码可能表示的最小值的负指数值,一般将其认为是0。
尾数上溢 两个同符号尾数相加产生了最高位向上的进位,将尾数右移,阶码增1来重新对齐。
尾数下溢 在将尾数右移时,尾数的最低有效位从尾数域右端流出,要进行舍入处理
定点数/浮点数比较可以看出
1.当浮点数和定点数中数的位数相同时,浮点数的表示范围比定点数大得多。
2.当浮点数为规格化数时,其相对精度远比定点数高。
3.浮点数运算要分阶码部分和尾数部分,而且运算结果都要求规格化,故浮点数运算步骤定点于是奶奶步骤多,运算速度比定点数运算低,运算线路比定点运算复杂。
4.溢出判断上,浮点数时对规格化数的阶码进行判断,而定点数是对数值本身进行判断及上述所说。
浮点数在数的表示范围、数的精度、溢出处理和程序编程等方面均优于定点数,但运算规则,运算速度及硬件成本方面不如定点数,计算机一般采用浮点数多。
溢出
溢出分为很多种比如.asp溢出 .ida/idq溢出 IIS ASP溢出、Apache分块编码溢出、openssh响应机制溢出,有符号/无符号溢出c语言中会有学到...........传统的溢出一般都是发生在字符串类型数据上面,用户提交数据超出程序分配的字符串大小,造成覆盖系统数据结构,最终导致程序流程改变。
我们最常见的是整形溢出和缓冲区溢出了
图片来源于网络
整形溢出可能会导致缓冲区溢出,缓冲区溢出会导致各种黑客攻击,OpenSSLde的hartbleed事件,就是一个buffer oberread的事件,Signed整形溢出大多数负数,很小几率是正数
缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在;利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果;可以利用它执行非授权指令,取得系统特权,进而进行各种非法操作。
操作系统所使用的缓冲区又被称为"堆栈".。在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。
缓冲区溢出攻击有多种英文名称:buffer overflow,buffer overrun,smash the stack,trash the stack,scribble the stack, mangle the stack, memory leak,overrun screw;它们指的都是同一种攻击手段。第一个缓冲区溢出攻击--Morris蠕虫,发生在1988年,由罗伯特,莫里斯(R ob。rtMorris)制造,它曾造成全世界6000多台网络服务器瘫痪。
在当前网络与6漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。
图片来源于网络
溢出攻击原理
通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。例如下面程序:
void function(char *str) {
char buffer;
strcpy(buffer,str);
}
上面的strcpy()将直接把str中的内容copy到buffer中。这样只要str的长度大于16,就会造成buffer的溢出,使程序运行出错。存在象strcpy这样的问题的标准函数还有strcat(),sprintf(),vsprintf(),gets(),scanf()等。
当然,随便往缓冲区中填东西造成它溢出一般只会出现“分段错误”(Segmentation fault),而不能达到攻击的目的。
最常见的手段是通过制造缓冲区溢出使程序运行一个用户shell,再通过shell执行其它命令。如果该程序有root或者suid执行权限的话,攻击者就获得了一个有root权限的shell,可以对系统进行任意操作。
缓冲区溢出攻击之所以成为一种常见安全攻击手段其原因在于缓冲区溢出漏洞太普遍了,并且易于实现。而且,缓冲区溢出成为远程攻击的主要手段其原因在于缓冲区溢出漏洞给予了攻击者他所想要的一切:植入并且执行攻击代码。被植入的攻击代码以一定的权限运行有缓冲区溢出漏洞的程序,从而得到被攻击主机的控制权。所以编写正确的代码是一件非常有意义的工作。想要深入可搜索这方面内容进行学习哦!
补充上期补码内容:补码只有8位时,最高位第九位自然丢失,即验证了正数的补码为该正数本身。
最后告诉大家是很多东西是必须要做的,比如?学习啊!哈哈。想要在计算机领域走的更远的话,英语数学这两门科目很很重要。放下你手中的游戏,抖音、短视频....来跟我一起学习,一起交流,一起成长吧!如果你连自己都控制不住的话,怎么掌控你的人生?
好啦本期内容就结束了,喜欢的朋友记得点赞评论转发收藏加关注哦!,
作者: TianshiyuMogui
著作权归作者所有侵权必究,商业转载请联系作者获得授权,非商业转载请注明出处,如有哪侵权请联系作者删除。