我在动作中有一个数字,通过一些任意数学得出:
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的数字的任何部分?
答案 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),舍入,然后除以相同的幂。