サイトトップ

Director Flash 書籍 業務内容 プロフィール

Macromedia Flash非公式テクニカルノート

数値の切捨てや四捨五入の最適化

ID: FN1109002 Product: Flash CS4 and above Platform: All Version: 10 and above/ActionScript 3.0

数値の切捨てや四捨五入には、MathクラスのメソッドMath.floor()Math.round()が使われます。けれど速い計算が求められるときには、ほかのやり方を採った方がよい場合もあります。


01 正数の切捨て
切捨てするのが正の数と決まっているときには、Math.floor()メソッドでなくint()またはuint()関数を使った方がずっと速いです(Flashデベロッパーセンター「ActionScript 3.0におけるパフォーマンス向上のヒント」06「数値の演算」参照)。これらの関数の呼出し方は、基本的にMath.floor()メソッドと同じです。ただし、戻り値のデータ型がintまたはuintに変わるという違いはあります。

Math.floor(数値:Number):Number

int(数値:Number):int

uint(数値:Number):uint

正数の切捨てには、ビット単位の論理和演算子|を使うことも考えられます。0との論理和をとると、数値の整数部はそのまま変わりません(前出「数値の演算」の「ビット演算」の項参照)。しかし、ビット単位の演算子は数値を整数(int型)として扱うため、小数部が切捨てられるのです。

数値 | 0

筆者の環境では、関数int()およびuint()とビット単位の論理和演算子|との間には、速さの明らかな差は認められませんでした。結果を確かめやすいように、wonderflにテスト用のコードを投稿しました。

Rounding down a positive number - wonderfl build flash online


02 正数の四捨五入
前項01「正数の切捨て」の考え方は、四捨五入にも活かせます。数値に0.5を足して切捨てれば、四捨五入した整数が得られるからです。もちろん、数値は正の数でなければなりません。

int(数値 + 0.5)
uint(数値 + 0.5)

(数値 + 0.5) | 0

これらの式の方が、Math.round()メソッドの計算よりずっと速いです。wonderflのテスト用コードで、Math.round()メソッドとint()関数による計算を比べてみました。

Comparing two formulas to round a number to an integer - wonderfl build flash online


03 正負の数を切捨てる
負の数の切捨てについては、ふたとおりの計算の考え方があります。Math.floor()メソッドとint()関数の違いがそれです。同じ正負の数値を引数に渡したとき、それぞれの戻り値はつぎの表001のようになります。

表001■正負にまたがる引数に対するMath.floor()メソッドとint()関数の戻り値
引数 Math.floor() int()
-2.5 -3 -2
-1.5 -2 -1
-0.5 -1 0
0.5 0 0
1.5 1 1
2.5 2 2

直感的にわかりやすいのはint()関数の計算でしょう。正の1.5を1とし、負の-1.5は-1になります。絶対値が正負で変わりません。けれど、表001の結果を見比べると、0を中心とした対称の計算です。それは、正と負で扱いが違うことを意味します。

それに対して、Math.floor()メソッドは引数の正負に拘らず、つねにその数値を超えない最大の整数を返します。プログラミングでは多くの場合、値によって扱いの変わらない演算の方が使いやすいです。そこで、負の数値でもMath.floor()メソッドと戻り値が同じ関数を、int()関数で定義します。

スクリプト001■正負の引数についてMath.floor()メソッドと同じ整数を返す関数
  1. function xFloor(n:Number):int {
  2.   var i:int = int(n);
  3.   if ((n < 0) && (i != n)) {
  4.     --i;
  5.   }
  6.   return i;
  7. }

スクリプト001は、負の引数を切り分け、小数点以下の端数がない場合を除いて整数を1減らしています(第3〜5行目)。素のint()関数にはかなり劣るものの、Math.floor()メソッドより1〜2割速いようです。wonderflのテスト用コードをご参考までに掲げます。

Optimizing Math.floor() method by using int() function - wonderfl build flash online



作成者: 野中文雄
作成日: 2011年9月26日


Copyright © 2001-2011 Fumio Nonaka.  All rights reserved.