VC++中的一个不足及其改善方法

来源:互联网 发布:linux 变量 引用 编辑:程序博客网 时间:2024/03/29 01:23

 

VC++中的一个不足及其改善方法

上海七○四研究所
梁柏林

---- 使用C语言编程序,有时需要把一种数值(如float类型的数值)转换成另一种类型(如int类型)的数值使用,这时,我们就要用到类型强制转换运算符,如(int)、(float)等。但是在VC++中,当把一个float类型的数值转换成int类型时,有时会出现比较大的误差。我在工作过程中就碰到过,当我把一个值为1140.00的float型变量ftemp使用如下方法转换成int类型,

itemp=(int)ftemp;

这时,int型变量itemp的值为1139,误差1(在本文中,我称这种误差为“1误差”)。这么大的误差,我们是不能接受的。

---- 经过深入的测试研究,我发现:在VC++中,当一个float型变量初始化(从屏幕输入一值,或把一常量值赋给它)后就用以上方法转换成int类型,结果是小数部分去掉,整数部分保留,误差小于1,没有“1误差”;而当一个float型变量初始化后,又经过一些运算,再转换成int类型,就可能会有“1误差”,就是说,结果不但把小数部分去掉,整数部分也可能有改变。例如,我们把以米为单位的数据转化成以厘米为单位的数据,用float型变量f存放以米为单位的数据,用int型变量i存放以厘米为单位的数据,使用下面语句实现数据转换。

i=(int)(f*100);当f=11.40(米)时,i=1139(厘米);当f=11.41(米)时,i=1140(厘米);当f=12.32(米)时,i=1231(厘米);当f=12.33(米)时,i=1232(厘米);等等,很多数据的转换存在着“1误差”。不过,大部分数据的转换是没有误差的,如当f=11.39(米)时,i=1139(厘米);当f=12.31(米)时,i=1231(厘米)。如果改用以下方法实现数据转换,“1误差”一样存在。float ftemp;ftemp=f*100;i=(int)ftemp;这里,ftemp是一局部变量(函数内定义)或全局变量(函数外定义)。把f*100改成f*100.0,“1误差”也存在。但是如果把ftemp改成为类的属性变量(在类里定义),“1误差”就不存在。

---- 我还发现,“1误差”现象对正负数具有对称性。就是说,如果有“1误差”,对于正数,(int)转换后少了1;对于负数,(int)转换后多了1。如上例子中,当f=-11.40(米)时,i=-1139(厘米);当f=-11.41(米)时,i=-1140(厘米);当f=-12.32(米)时,i=-1231(厘米);当f=-12.33(米)时,i=-1232(厘米)。而且,转换误差不会大于1。

---- 针对以上分析结果,我在这里给出一个校正“1误差”的方法,以供参考。我设计了一个把float型数转换成int型数的函数,用以代替(int)运算符。函数清单如下:

int float_to_int(float f){int i;float ferror;i=(int)f;ferror=f-(float)i;if(fabs(ferror)>0.99)//有“1误差”,校正if(f>0)i++;elsei--;return(i);}

---- 在此函数中,通过判断(int)类型转换前后的误差ferror是否大于0.99来判断是否有“1误差”,如果有,就进行校正。校正方法是,对于正数,把(int)转换结果加1;对于负数,把(int)转换结果减1。

---- 定义了float_to_int()函数后,用它代替(int)运算符就能校正“1误差”了。如对上面把以米为单位的数据转化成以厘米为单位的数据这一例子来说,改成

i=float_to_int(f*100);或float ftemp;ftemp=f*100;i=float_to_int(ftemp);当f=11.40(米)时,i=1140(厘米);当f=11.41(米)时,i=1141(厘米);当f=12.32(米)时,i=1232(厘米);当f=12.33(米)时,i=1233(厘米);当f=-11.40(米)时,i=-1140(厘米);当f=-11.41(米)时,i=-1141(厘米);当f=-12.32(米)时,i=-1232(厘米);当f=-12.33(米)时,i=-1233(厘米)。“1误差”没有了。而且对原来没有“1误差”的数据也没有影响,如当f=11.39(米)时,i=1139(厘米)。通过对大量的数据进行测试检查,证明此方法是有效的。

---- 另外,对于double型转换成int型,也有类似的“1误差”问题,只是出现误差的数据比较少,而且还有偶然性(就是,对于某个数值,有时候有“1误差”,有时候又没有“1误差”)。应用类似的方法也可以把double型转换成int型的“1误差”校正过来。




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 起亚k3钥匙没电怎么办 汽车摇控钥匙失灵了怎么办 逍客钥匙没有电怎么办 车钥匙芯片坏了怎么办 车钥匙密码丢了怎么办 遥控车钥匙丢了怎么办 车备用钥匙丢了怎么办 2把车钥匙丢了怎么办 汽车遥控钥匙丢了怎么办 车钥匙忘在车里怎么办 轩逸钥匙没电了怎么办 车钥匙锁后备箱怎么办 死飞车掉漆了怎么办 被吸血蝙蝠咬了怎么办 pos失败钱扣了怎么办 现金支票写错了怎么办 公路上汽车坏了怎么办 驾图盒子绑定过怎么办 车在路上没油了怎么办 狂野飙车8闪退怎么办 宜家会员卡没带怎么办 飞猪机票买贵了怎么办 发现机票买贵了怎么办 埋线双眼皮松了怎么办 吸气时左胸口疼怎么办 兰芝隔离有气泡怎么办 19岁眼部有皱纹怎么办 三星s4开不了机怎么办 三星手机变砖了怎么办 面霜一次用多了怎么办 午觉睡多了头疼怎么办 下午睡多了头疼怎么办 白天睡久了头疼怎么办 睡觉睡多了头痛怎么办 泡菜坛子水少了怎么办 咸菜坛子生花了怎么办 四川泡菜生花了怎么办 三岁宝宝说话不清楚怎么办 电脑读不出来u盘怎么办 跳绳的时候漏尿怎么办 喝完酒一直想吐怎么办