三:计算机进行小数运算时出错的原因

0、开篇:

(1)二进制数0.1,用十进制数表示的话是多少?

0.5

(2)用小数点后有3位的二进制数,能表示十进制数0.625吗?

可以,0.101

(3)将小数分为符号、尾数、基数、指数4部分进行表现的形式称为什么?

浮点数(浮点数形式)

(4)二进制数的基数是什么?

2

(5)通过把0作为数值范围的中间值,从而在不使用符号位的情况下来表示负数的表示方法称为什么?

EXCESS系统表示(EXCESS是“剩余的”的意思。例如,把01111111看作是0的话,比这个数小1的01111110就是-1)

(6)10101100.01010011这个二进制数,用十六进制数表示的话是多少?

AC.53

1、将0.1累加100次也得不到10

2、用二进制数表示小数

  先来一个热身,把1011.0011这个有小数点的二进制数转换成十进制数(前面章节已经讲过了用二进制来表示整数的方法,其实小数也一样),如下图所示:

  

3、计算机运算出错的原因

   通过第2节的学习,大家应该也能大概知道计算机运算出错的原因了:是因为“有一些十进制数的小数无法转换成二进制数”。例如十进制数0.1,就无法用二进制数正确表示,小数点后面即使有几百位也无法表示。

 我们就看小数点后4位用二进制数表示时的数值范围0.0000~0.1111,如下图所示:

  

  这里只能表示0.5 、 0.25 、 0.125 、0.0625这四个二进制数小数点后面的位权组合而成(相加总和)的小数。再回到我们要表示的0.1,怎么加都无法加到0.1的,只会变成0.00011001100...(1100的循环),不信你可以去试试。

说到这里,大家应该都能明白为什么将0.1累加100次也得不到10的原因了把,因为无法正确表示的数值,最后都变成了近似值。计算机是一个功能有限的机器设备,是无法处理无限循环的小数的,一般计算机都会从中间截断。

4、什么是浮点数

  像1011.0011这样带小数点的表现形式,完全是纸面上的二进制数表现形式,在计算机内部是无法使用的。这一章节主要是说明计算机是以什么样的表现形式来处理小数。很多编程语言中都提供了两种表示小数的数据类型,分别是双精度浮点数与单精度浮点数。双精度浮点数类型用64位、单精度浮点数用32位来表示全体小数。从C语言中,双精度浮点数类型和单精度浮点数类型分别用double和float来表示。

  浮点数是指符号、尾数、基数和指数这四个部分来表示的小数,如下图:

  

  因为计算机内部使用的是二进制,所以基数自然就是2.因此,实际的数据中往往不考虑基数,只用符号、尾数、指数这三部分即可表示浮点数。也就是说,64位(双精度浮点数)和32位(单精度浮点数)的数据,会被分为三部分来使用,如下图展示:

  

 ① 符号部分:是指使用一个数据位来表示数值的符号。该数据位是1时表示负,为0时则表示“正或者0”。

② 尾数部分:数值大小的决定部分之一(另外一个是指数部分)。尾数部分用的是“将小数点前面的值固定为1的正则表达式”。

③ 指数部分:用的则是EXCESS系统表现。

5、正则表达式和EXCESS系统

   ① 尾数部分使用正则表达式,可以将表现形式多样的浮点数统一为一种表现形式。例如十进制的0.75就有很多种表现形式:

   

正因为表现形式太多,计算机处理时就会比较麻烦。因此,为了方便计算机处理,需要制定一个统一的规则。例如,十进制数的浮点数应该遵循“小数点前面是0,小数点后面第1位不能是0”这样的规则。根据这个规则,0.75就是“0.75 * 10的0次幂”,也就是说,只能用尾数部分是0.75、指数部分是0这个方法来表示。根据这个规则来表示小数的方式,就是正则表达式。

二进制数也是同样的道理,在二进制数中,我们使用的是“将小数点前面的值固定为1的正则表达式”。具体来讲,就是将二进制数表示的小数左移或右移(这里是逻辑移位。因为符号位是独立的)数次后,正数部分的第1位变为1,第2位之后都变为0(这样是为了消除第2位以上的数位)。而且,第1位的1在实际的数据中不保存。由于第1位必须是1,因此,省略该部分后就节省了一个数据位,从而也就可以表示更多的数据范围。

下图是单精度浮点数的正则表达式的具体例子(单精度浮点数中,尾数部分是23位):

  

6、在实际的程序中进行确认

  对EXCESS系统与正则表达式了解了吗,如果还没有了解,就返回上一小节再看一看,我也是看了几遍才看懂的,如果看懂了,就往下看,用C语言程序来确认单精度浮点数表示方法。

7、如何避免计算机计算出错 

  计算机计算出错的原因之一是采用浮点数来处理小数(另外,也有因“位溢出”而造成计算错误的情况)。作为程序的数据类型,不管是使用单精度浮点数还是双精度浮点数,都存在计算出错的可能性。接下来会介绍两种避免该问题的方法。

① 回避策略,即无视这个错误,只要得到近似值就可以了,那些微小的误差完全可以忽略掉。

② 把小数转换成正数来计算。

8、二进制数和十六进制数 

  最后补充说明一下二进制数和十六进制数的关系。在实际程序中,如果二进制位数太多,看起来会比较麻烦,因此,在实际程序中,也经常会用十六进制数来代替二进制数。二进制数的4位,正好相当于十六进制数的1位。例如,32位二进制数00111101110011001100110011001101用十六进制数来表示的话,就是3DCCCCCD这个8位数。由此可见,通过使用十六进制数,二进制数的位数能够缩短至原来的1/4 。

用十六进制数来表示二进制小数时,小数点后的二进制数的4位同样相当于十六进制的1位。不够4位时用0填补二进制数的低位即可。例如,1011.011的低位补0后为1011.0110,这时就可以表示为十六进制数B.6 。

 

时间: 2024-10-10 07:09:46

三:计算机进行小数运算时出错的原因的相关文章

计算机进行小数运算时出错的原因和避免方法

计算机进行小数运算时出错的原因: 是因为有一些十进制的小数无法转换成二进制数. 如何地避免小数运算错误: 1.回避策略,即无视这些错误.根据程序目的不同,有时一些微笑的偏差并不会造成什么问题 2.就是把小数转换成整数来计算.计算机计算小数时可能会出错,但进行整数计算时一定不会出现问题.因此我们可以将小数暂时转换成整数在输出的时候再以小数的形式来输出 原文地址:https://www.cnblogs.com/hyy123-/p/10664879.html

第三章计算机进行小数运算时出错的原因

以前的我以为计算机是什么都可以做的不会出现什么错误,但我看完这一章以后我才知道,计算机在程序运行后无法得出自己想要的结果,就是十进制转换二进制时,出现了小数的情况 下边我可以通过这个例子就能看出来: #include <studio.h> void main() { float sum; int i; sum = 0; for(i = 1; i <= 100;i++){ sum+=0.1: } print f ("%f\n", sum); } 在这个程序中我们可以看到

计算机进行小数运算会出错

float sum=0; for(int i=0;i<100;i++) sum+=0.1; System.out.print(sum);//10.000002 原因:计算机计算数字时,使用的是二进制,而十进制的0.1,无法用二进制精确表示,是一个二进制循环数,0.00011001100……(1100循环),而计算机对此二进制进行截取后,进行累加操作,必然会出现结果不对的情况.

JS操作小数运算,结果莫名其妙出现多位小数问题

Number类型: Number类型是ECMAScript中最常用和最令人关注的类型了:这种类型使用IEEE754格式来表示整数和浮点数值(浮点数值在某些语言中也被成为双精度数值),为支持各种数据类型,ECMA-262定义了不同的数值面量格式. 十进制: var intNum=10; //整数 八进制: var octalNum1=070; //八进制的56 var octalNum2=079; //无效的八进制数值-解析为79 八进制字面量在严格模式下是无效的: 十六进制: var hexNu

JS小数运算失精度的问题

浮点数值的最高精度是17位小数,但在进行运算的时候其精确度却远远不如整数:整数在进行运算的时候都会转成10进制: 而java和JavaScript中计算小数运算时,都会先将十进制的小数换算到对应的二进制,一部分小数并不能完整的换算为二进制,这里就出现了第一次的误差.待小数都换算为二进制后,再进行二进制间的运算,得到二进制结果.然后再将二进制结果换算为十进制,这里通常会出现第二次的误差. 所以(0.1+0.2)!=03 解决这种问题,可以将小数变成整数进行运算,然后再将结果变为小数. var ca

匹夫细说C#:妥协与取舍,解构C#中的小数运算

题外话 正文开始之前,我首先要感谢博客园提供的这个优秀的平台.通过在这个优秀的平台上和很多志同道合的朋友交流,互相帮助,我也很荣幸的获得了15年的微软MVP的奖项.也使我更加坚信了代码改变世界.感激!感恩!努力!加油! 0x00 前言 慕容在生活和工作中常常会遇到一些十分迷信机器的人,他们之中很多人都相信机器是最理智的,没有任何感情,是真正的铁面无私,因此机器的运算所给出的答案总是正确的,如果答案错误,那么一定是操作机器的人的问题.但机器的运算就一定是正确的吗?事实上,机器出现运算错误并不是一个

第三章、三元运算、文件处理、函数

第三章.三元运算.文件处理.函数 三元运算 三元运算又称三目运算,是对简单的条件语句的简写,如: 简单条件语句: if 条件成立: val = 1 else: val = 2 # 可以写成如下: val = 1 if 条件成立 else 2 文件处理 读,写,修改 读 f = open(file='d:/*.txt', mode='r', encoding='utf-8') date = f.read() f.close() r是只读模式,rb是以二进制读文件 第三方模块 chardet检测二进

细心!SQL语句进行运算时使用字符串时缺失精度的细节!

昨天没有更新,特此来说明下原因,昨天回到家时已经甚晚,正逢公司这几天项目比较紧张(bug多,赶需求,看着bug单齐刷刷的转过来,心都颤抖了一下),没有及时准备素材,今天又加了一天班(现在还在公司,偷个空隙赶紧发博,哈哈哈),所以昨晚没有更博. 今天在改bug的时候发现了如图的小问题,来分享一下,主要还是要细心. 我们有一个页面,需要输入数字传入后台,然后进行相关的运算,再通过运算后的数进行查询,我们页面输入值传入后台的是String类型的,进行运算后得出一个缺失精度的值,而我们用来查询时把这个数

计算机数制和运算的一点总结.

一.为什么会有10进制, 2进制,8进制,16进制? 10对我们来说是一个非常重要的数字.10是我们大多数人拥有的手指或脚趾的数目,因而我们人类已经适应了以10为基础的数字系统. 我们通常使用的数字系统称为以10为基础的数字系统或十进制.这个数字系统对我们来说非常自然,因而我们很难想像出还有其他的数字系统.如果人类不是有那么多只手指,我们数数的方式就会有所不同,数字10就可能代表别的东西了.当我们明白了10可以指只有两只鸭子的时候,也就可以解释开关.电线.灯泡.继电器(或干脆就叫计算机)是怎样表