截断Actionscript编号

时间:2012-06-07 00:26:25

标签: actionscript

我在动作中有一个数字,通过一些任意数学得出:

var value:Number = 45 * (1 - (1 /3));
trace(value);//30.00000000004

现在,我想取这个数字的上限,除非它大于下一个较低整数的数量小于某个epsilon。在上面的例子中,我真的想要舍入到30,但只有在我知道我得到舍入错误的情况下:

Math.ceil(value); //I want 30, but get 31
Math.ceil(30.1);  //In this case, it's reasonable to get 31

是否有一种优雅的方法来截断动作中的数字?或者轻易地丢弃少于某个epsilon的数字的任何部分?

3 个答案:

答案 0 :(得分:2)

这种方法对你有什​​么帮助吗?

var precision:int = 4;
var isActualCeilingValRequred:Boolean;
var thresholdValForCeiling:int = 100;

private function getCeilingValue(num:Number):Number
{
  var tempNum = num * Math.pow(10, precision);
  var decimalVal = tempNum % Math.pow(10, precision);

  if(decimalVal < thresholdValForCeiling) {
    return Math.floor(num);
  } else {
    return Math.Ceil(num);
  }
}

答案 1 :(得分:1)

var value:Number = 45 * (1 - (1 /3));
trace(value);//30.00000000004

// Play with arbitraryPrecision until you are satisfied with
// the accuracy of your results
var arbitraryPrecision:int = 3;
var fixed:Number = value.toFixed(arbitraryPrecision);

trace(Math.ceil(fixed));

答案 2 :(得分:0)

将数字舍入到指定数量的小数位数的基本方法是将数字乘以10 ^ DIGITS以将小数点DIGITS数字向左移动,执行舍入,并除以相同的10 ^ DIGITS将小数点移回右侧。

var value:Number = 45 * (1 - (1 / 3));
trace(value); // 30.000000000000004
trace(Math.ceil(value)); // 31
// Round the number to 13 decimal digits.
const POWER:Number = 1e13;
value = Math.round(value * POWER) / POWER;
trace(value); // 30
// Compute number's ceiling.
value = Math.ceil(value);
trace(value); // 30`

它适用于你的例子,但有一个很大的问题。如果您将值更改为450 * (1 - (1 / 3));,则原始问题将再次出现。现在要摆脱它,你将不得不舍入到12位小数。基本上,双精度格式(Number)的有效位数可以包含大约15位有效数字。这意味着当值增加十倍时,小数点向左移动,而您想要摆脱的最后一个“4”数字越来越接近小数点。因此代码变得更加复杂。

var value:Number = 450 * (1 - (1 / 3));
trace(value); // 30.000000000000004
trace(Math.ceil(value)); // 31
var exp:Number = Math.floor(Math.log(Math.abs(value)) * Math.LOG10E);
trace('exp=' + exp); // exp=2
const POWER:Number = Math.pow(10, 14 - exp);
value *= POWER;
trace(value); // 300000000000000.06
value = Math.round(value);
trace(value); // 300000000000000
value /= POWER;
trace(value); // 300

正如您所看到的,无论价值的大小如何,它现在都有效。 首先,我通过取数字的绝对值的10对数,然后将其四舍五入来找到数字的指数。如果计算a = value * Math.pow(10, exp);,则值可以表示为* 10 ^ b,其中(1≤| a |&lt; 10),称为标准化科学记数法。但那不是我们在这里做的。现在我们知道小数点左边有多少位数,我们将右移小数点,但不要太远,以保持一个0和我们想要摆脱的这个错误数字,在右侧小数点。因此,乘以10 ^(14-exp),舍入,然后除以相同的幂。