数値を指定された小数桁数に丸める基本的な方法は、数値を 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) を掛けて四捨五入し、同じ累乗で割ります。