1、Number
Number是一个双精度浮点数,而as中很多属性值是此类型。在实际编程中,如果要精确控制Number,会出现莫名其妙的情况,
情况一、
函数y=f(x)=a*x/k,其中x为自变量,x、k均为整数,由此计算出y,然后立即由k*y/a返求x,这个x算出来不完完整整正好是原来的x!可能算出来是一个与原x有微弱差别的Number小数(譬如多或者少个0.000001等等),这时如果你使用x的下界或者上界,会出现错误!
情况二、
判断两个Number是否相等,我们经常算出一个Number来,来判断与某定义的标定值进行判断,这时大家一定要注意,因为计算出来的可能是0.9999999999,而你的标定值是1.0,这时进行判断,会出现莫名其妙的问题
情况三、
如殿堂之路所言,小数相加不一定得到整数,数值差距过大的浮点数加减结果有偏差。
2、drag
肯定有很多人用startdrag(lockCenter:Boolean, bounds:Rectangle)来拖拽显示元件,大家一定要注意,drag是有精度限制的,它一般拖拽出来的元件的x或者y大部分是整数,如果你的bounds设定的范围不是一个整数,一般在范围边界处并不能完整重合,大家可以自己去试。这里也给一个例子,拖动到右侧边界后,可以放大以显示边界重合情况。
3、显示对象的几何属性
可能有人喜欢用某显示对象的x、y、width、height等作为自变量用于数学计算,但是这里要提醒的是,这些都是属性自身就是不精确的,如果你要用于高精确计算是不现实的。大家可以自己测试下:
如果想要通过计算然后改变这些几何属性值,再根据这些几何属性值计算其他变量,因为几何属性的精度问题可能导致最终的变量值出现错误!mc.x = 10/3;
trace(mc.x, 10/3);
mc.x = 8.505;
trace(mc.x, 8.505);
4、解决方案
一、Math的中有很多与浮点数修整相关的方法
Math.ceil--上界:譬如0.1、0.8、0.9999都会返回1(如果源是整数,不改变)
Math.floor--下界:譬如0.1、0.8、0.9999都会返回0(如果源是整数,不改变)
Math.round--四舍五入
二、对于比较浮点数相等,可以自定义定义一个静态常量代表精度,类似于Math的PI,判断二者的差值得绝对值是否小于该精度,小于则认定相等
public static const EPSILON:Number=0.01;
判断时
Math.abs(a-b) <= EPSILON 代替 a==b
三、drag中最好把bounds矩形修整为整数宽高以及起始,如果是根据某元件的属性来设定这个矩形,则修整该元件的宽高。
四、尽量不要用显示对象的几何属性用于高精度数学计算(前提是这些几何属性是计算出来并且动态赋的),单独建立一个number变量来对应这个原始计算出来的几何属性并采用这个变量用于高精度计算。
即:
var YFlag:Number = 0;
mc.y = YFlag = 10/3;
trace(mc.y, YFlag, 10/3);
//以后用YFlag代替mc.y进行高精度计算