当前位置:C++技术网 > 资讯 > C++语言零基础入门教程:4.5 小数(浮点数)在编程中的运用详解

C++语言零基础入门教程:4.5 小数(浮点数)在编程中的运用详解

更新时间:2016-07-26 22:51:23浏览次数:1+次

    不知不觉,已经过了四个月了,教程一直停在这里。我一直心里挂念着,放心不下。期间各种忙,工作上的,网站上的,让人心力憔悴,也就没有更新教程了。特别是近来心态不好,导致心情也不是很好。网站做的真心累,没有经济上的激励,而且入不敷出,连小团队的人都没有激情了。最后到现在,又似乎回到了一个人孤军奋战的感觉。心累!
    我知道,教程更新太慢,但是没有办法。技术站不好做,成本都收不回来,更不谈投入的精力心血。所以,只是业余时间来写教程,还有很多时间要维护网站。况且,我不想随便更新一下教程,罗列一下知识点。所以,很慢,请理解。只能尽量更新,或者采用会员形式来阅读,或许能给我一点激情。
    上一节我们讲到了《C++语言零基础入门教程:4.4 小数点数据类型的哲学思想分析》,从思想上做了详细的分析。将一个整数变成一个小数,我们既可以用乘法也可以用除法。两种方法有什么区别吗?当然是有的。下面先说一下。
    我们用整数表示不能用完整单位表示的数量的时候,我们可以用分数,比如1/10.我们用小数表示就可以看成是0.1。我们习惯性的会对分数做一个运算,即1÷10=0.1,很少有人会自然而然的用1*0.1=0.1来计算,为什么?因为分数在形式上和除法很相像。分数应该算是一个比例表示法,实际上和没有直接关系。
    假如你在编程中,遇到用两个数的计算得到小数,你会怎么做?我想最直接的就是相除。不过你要多了解一点。在除法算式中,除数是不能为0的。在编程的数值变化中,经常会出现除数变成0而造成崩溃,也就是计算机遇到了“除零错误”。
    当我们习惯用除法来得到小数的时候,就很容易陷入“除零错误”。如果我们换一个角度来想,我们就可以避开“除零错误”。我们要学会使用乘法来代替除法运算。假如在显示进度条的时候,总数值为20,进度值从0开始,那么0/20.0、1/20.0、10/20.0、20/20.0,这样的来表示一个进度过程。这样的做法和我们默认的习惯是一致的,很好理解,也很好实现。如果我们换成乘法来表示,需要这样:0x5x0.01、1x5x0.01、10x5x0.01、20x5x0.01。乘法和除法表示是等价的,但是从思想上却有所改变。乘法可以规避“除零错误”,这样让你在一些数据处理的时候,适应了乘法替换除法,来做一些常规的数据变化的计算,可以避开“除零错误”。
    如果你要争辩,说你会小心,不想搞得这么麻烦,那你就直接用除法好了。但是你需要知道有这样的一个形式。
    在常规的编程中,一般对于小数的处理,都是很简单的。除非做专门的数学处理运算之类的编程,可能会涉及小数更多的更深入的细节。不过对于一般情况的编程,我们无需了解那么多。更何况,很多初学者一开始连float、double都傻傻分不清楚。
    对于整数来说,整数的表示关心数值的范围,最大值和最小值。因为计算机表示数值的位数有限,整数也就有了一个相对的范围,这是计算机世界的规则,在数学世界中,整数是没有范围的,也就是没有最大值和最小值。所以,整数的理解也是初学者最先掌握的。不过,多数初学编程的人都没有意识到为什么整数类型有范围,甚至根本没有想过这个问题,毕竟书上都说好了,只需要记忆或者了解范围计算的原理,殊不知,没有多少去思考整数类型为什么有范围,或者说,计算机数据类型为什么有范围?那是因为计算机表示的能力有限,而数学的数值范围是逻辑上的,你能想到多远,数据就有多大。毕竟,想象是没有终点的。如果哪一天,人类的想象力有限了,那么可能数值范围也就有了最大值和最小值,这是类比计算机表示能力的,只是一个类比,在数学上不一定正确,数学的定义也就意味着数值是无穷大和无穷小的。
    这里只是给你一个启示而已。同样,对于小数来说,也是有范围的,原因还是计算机表示能力有限,不过计算机表示的小数范围可以很大很大了,够我们的需要了。小数不仅仅有范围,还有一个特点,那就是精度。
    精度是什么?精度就是精确程度。小数是表示不足一个单元的数量而存在的。也就是说,在给定的单元大小的前提下,我们要丈量更小的量,就只有用小数了。然而能够表示到多小,就是精确度问题了。能够丈量的尺度越小,精度越高。
    在整数的角度来讲,单位越小,精度越高。但是对于整数来说,我们一般不会说精度这个问题。在纯数字表示的时候,没有任何单位,你想赋予什么单位都行。对于小数才无时无刻的要提到精度问题。因为小数的小数点后面的数字越多,也就越精确。小数点后面的数字可以转换为更小单位的数值,如果小数点后面的数字越多,最小单位也就不断的在变小。1.10和1.100000是有区别的,1.100000的精度更高。虽然两个数的数值是一样的,然而精度不一样,就有了很大的区别了。
    首先要是的是表示能力。精度和范围都是一个数据类型的表示能力的度量。大家表示同样的范围,一个能够更加精确,自然也就可以出类拔萃。当大家都有一样的精度,范围大的就可以脱颖而出。如果一个精度又高,范围又大,那就可以“称霸武林”了。范围好比力量,精度好比准确度,力量大,准确度高,伤害值就最高了。
    另外,在计算机内部实现不同精度的数值,也是有所区别的。精度越高,也就需要更多的内存位来表示。数值的每一个位都需要内存来支持的,而不是用人脑来支持的。
    那么在计算机编程中,小数被称为浮点数。浮点数是以浮动小数点的形式来表示的。内存中并没有表示一个点的东西。内存中存储的都是数字,没有存储小数点。不过在实现小数支持的时候,必然要让小数点加进去。我们可以用一个逻辑的数值,表示小数点的位置,改变这个数值,也就好像改变了小数点的位置,这样就改变了最终表示的数据值。这也就是浮点数名称的来源。这里是简单的解释,如果想要深入了解,请阅读相关专业书籍。对于初学者来接受浮点数就是数学中的小数,请看准“点”字。这个点字可以联想到小数点,也就是小数了。我开始学习的时候,总是很难将浮点数和小数这两个概念对应上。
    那么在C/C++中,用float、double表示浮点数。float是浮动的意思,double是双杀的双的意思。float和double都用于表示小数,两者的区别只是范围和精度的区别,都是一个妈生的。double名称的来源是因为double表示的精度是float的两倍的样子,所以一般叫做双精度小数double。也就是说,double更加强悍些,不过double需要计算机支持也就更多些,好比一把大斧头double和一个匕首float,大斧头威力更大,但是需要更多的力量去使用,需要更多的铁去铸造,而匕首同样可以伤人,但是使用轻便,需要的铁较少。
    所以说,在使用float和double的时候,不要认为double强悍就只用double。在数值范围比较小精度不要太高的时候,float就够了。对于日常生活的表示,float就够了。但是对于计算测量方面需要更高的精度的地方,float精度不够,小数点后的数字个数不够。此时需要使用double了。
    float的精度为6-7个小数点后的有效数字,而double的精度为15-16位,可以看出double的精度大概就是float的两倍,也就是双精度小数叫法的原因。
    那么对于小数数据类型的编程使用,这是最简单的一部分了。
float price=1.30;
float lon=1.301204;
double dd = 52.125245214;

    定义小数数据类型的变量和整型类型变量一样,只是类型的名称不一样而已。然后小数的加减乘除是在简单不过了。相信你看了点书就知道怎么回事。
    不过在涉及float和double的变量的混合运算的时候,如:
double rr = price+dd;

    我们的计算机处理原则是,尽可能保证数据准确,不让精度丢失。所以,在不同精度的小数计算时,会先将精度小的转化为精度高的,然后进行运算。结果就是精度高的数值。运算发生在同精度的数值之间,因为计算机计算总是在一个硬件运行的,硬件总是固定的,所以也就是对同样的精度的两个数值有一个同样的操作环境。在不同精度或者范围的两个数值处理之前,都会做一个类型统一化,然后再做运算。
    混合运算时,记住一个最基本的策略:防止数据运算中丢失范围或者精度。所以,小范围变量迁就大范围变量,小精度迁就大精度变量。小精度和小范围的运算环境中装不下大精度和大范围的数值,强行装进去就要么是头在外面,要么就是尾巴在外面,这样最后运算后斩断了头或者尾巴,数据就丢失了。
    编译器一般会对数据丢失最警告提醒,如果你能够确定数据运算不会超过小范围或者小精度变量,那么可以忽略警告,否则就要改善代码了。
    记住前面的基本策略和运算原理,你可以类推不同数据类型变量之间的运算的取舍问题,就不再详细说明了。