0

アクションスクリプトに数値があり、任意の数学を介して到達しました:

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

ここで、この数の上限を取りたいと思います。ただし、次に小さい整数よりも大きい量がイプシロンよりも小さい場合を除きます。上記の例では、実際には 30 に丸めたいのですが、丸めエラーが発生することがわかっている場合に限ります。

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

アクションスクリプトで数値を切り捨てるエレガントな方法はありますか? または、いくつかのイプシロン未満の数値の一部を簡単に破棄しますか?

4

3 に答える 3

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);
  }
}
于 2012-06-07T14:28:29.270 に答える
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));
于 2012-06-07T00:40:53.507 に答える
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 桁に丸める必要があります。基本的に、倍精度形式 (数値) の仮数部は、有効数字約 15 桁を保持できます。これは、値が 10 倍になると小数点が左に移動し、削除したい最後の "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);と、値は a * 10^b として表すことができます。ここで、(1 ≤ |a| < 10) は、正規化された科学的表記として知られています。しかし、それは私たちがここでやっていることではありません。小数点の左側の桁数がわかったので、小数点を右にシフトします。小数点。したがって、10^(14-exp) を掛けて四捨五入し、同じ累乗で割ります。

于 2015-06-22T17:24:01.103 に答える