« 動画には | Home | 懊悩日記 10/23-25 »

Oct 242009

32 ビットを超えたときのuintの挙動

32bitを超えた値だと、超過部分が-1に変化してしまう。
つまりこんな挙動になる。

var a:Array =[];
a.push(4294967295);
a.push(100);
a.push(4294967295);
a.push(100);
a.push(4294967295);
var total:uint = 0;
for (var i in a)
{
	total += a[i];
	trace(i,"@",total);
}
trace("finish",total);

実行結果

0 @ 4294967295
1 @ 99
2 @ 98
3 @ 198
4 @ 197
finish 197

ややこしいね。

例えば

var a:Array =[];
a.push(4294967295-90);
a.push(100);
a.push(4294967295);
a.push(100);
a.push(4294967295);
var total:uint = 0;
for (var i in a)
{
	total += a[i];
	trace(i,"@",total);
}
trace("finish",total);

とすると

0 @ 4294967205
1 @ 9
2 @ 8
3 @ 108
4 @ 107
finish 107

こーなる。
ああ面倒くさい。

ちなみにNumberは53 ビットまで使用可能なので、Numberで計算するとこんな感じになる。

var a:Array =[];
a.push(4294967295-90);
a.push(100);
a.push(4294967295);
a.push(100);
a.push(4294967295);
var total:Number = 0;
for (var i in a)
{
	total += a[i];
	trace(i,"@",total);
}
trace("finish",total);
trace("to uint = ",uint(total));

最後にuintに変換した部分は、また超過部分が-1で演算されるので答えは同じになってしまうけど・・。

0 @ 4294967205
1 @ 4294967305
2 @ 8589934600
3 @ 8589934700
4 @ 12884901995
finish 12884901995
to uint = 107

Leave a comment

Search and Archives