<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>整頓中（仮） &#187; ActionScript 3.0</title>
	<atom:link href="http://www.retropc.net/mm/archives/category/actionscript-30/feed" rel="self" type="application/rss+xml" />
	<link>http://www.retropc.net/mm</link>
	<description>ずっと仮</description>
	<lastBuildDate>Wed, 08 Feb 2012 13:51:36 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>ActionScript3.0 アルファ値のビット演算</title>
		<link>http://www.retropc.net/mm/archives/48</link>
		<comments>http://www.retropc.net/mm/archives/48#comments</comments>
		<pubDate>Sat, 28 Mar 2009 04:52:30 +0000</pubDate>
		<dc:creator>moriyan</dc:creator>
				<category><![CDATA[ActionScript 3.0]]></category>

		<guid isPermaLink="false">http://www.retropc.net/mm/?p=48</guid>
		<description><![CDATA[レンダリングの公式について、α値が意図した通りにならないことがあります。 [javascript toolbar="false"] for (var i = 0; i 16 &#038; 0xFF; var vg = color32 >> 8 &#038; 0xFF; var vb = color32 &#038; 0xFF; trace( color32.toString(16) + &#8220;:&#8221; + i.toString(16) + &#8220;:&#8221; + va.toString(16) + &#8220;,&#8221; + vr.toString(16) + &#8220;,&#8221; + vg.toString(16) + &#8220;,&#8221; + vb.toString(16) ); } [/javascript] 実行結果は以下の通り。 00102030:0:0,10,20,30 01102030:1:1,10,20,30 02102030:2:2,10,20,30 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog2.bonkura.jp/?p=300">レンダリングの公式</a>について、α値が意図した通りにならないことがあります。<br />
[javascript toolbar="false"]<br />
for (var i = 0; i <= 0xff; i++) {<br />
	var color32 = i << 24 | 0x10 << 16 | 0x20 << 8 | 0x30;<br />
	var va = color32 >> 24;<br />
	var vr = color32 >> 16 &#038; 0xFF;<br />
	var vg = color32 >> 8 &#038; 0xFF;<br />
	var vb = color32 &#038; 0xFF;<br />
	trace( color32.toString(16) + &#8220;:&#8221; + i.toString(16) + &#8220;:&#8221; + va.toString(16) + &#8220;,&#8221; + vr.toString(16) + &#8220;,&#8221; + vg.toString(16) + &#8220;,&#8221; + vb.toString(16) );<br />
}<br />
[/javascript]<br />
実行結果は以下の通り。<br />
<code><br />
00102030:0:0,10,20,30<br />
01102030:1:1,10,20,30<br />
02102030:2:2,10,20,30<br />
～<br />
7f102030:7f:7f,10,20,30<br />
-7fefdfd0:80:-80,10,20,30<br />
-7eefdfd0:81:-7f,10,20,30<br />
～<br />
-1efdfd0:fe:-2,10,20,30<br />
-efdfd0:ff:-1,10,20,30<br />
</code><br />
まず最初のα,r,g,bを表す32bit値が符号付きになってしまっています。これは演算結果自体は正しいのですが、toString()で変換する時に符号付きの数値だと判断されているだけですから、あまり問題ではないと思います。それでも気になるのであれば、変数宣言時にuint型として指定すればいいようです。<br />
[javascript gutter="false" toolbar="false"]<br />
var color32:uint = i << 24 | 0x10 << 16 | 0x20 << 8 | 0x30;<br />
[/javascript]</p>
<p>次に気になるのが、32bitのカラーコードから、α,r,g,bを切り出すところで、αが0x80を超えたところから符号付きになってしまっています。じゃあこれも同様にuintにすればいいのかというと...<br />
[javascript gutter="false" toolbar="false"]<br />
var va:uint = color32 >> 24;<br />
[/javascript]<br />
結果は<br />
<code><br />
7e102030:7e:7e,10,20,30<br />
7f102030:7f:7f,10,20,30<br />
80102030:80:ffffff80,10,20,30<br />
81102030:81:ffffff81,10,20,30<br />
</code><br />
うまくいきません。これはActionScriptのマニュアルで“ビット単位シフト演算子”の項目を読むとわかるのですが、&gt;&gt;は、ビット単位の右シフト、&gt;&gt;&gt;は、ビット単位の符号なし右シフトと書かれています。読み替えると、&gt;２個は符号付きの右シフトということなので、32ビット値を符号付きで右シフトすると最上位ビットが残ってしまうのですね。</p>
<p>「符号付きの右シフトって何？」という場合は検索してください。</p>
<p>α値を取り出す箇所は以下のようになります。<br />
[javascript gutter="false" toolbar="false"]<br />
var va = color32 >>> 24;<br />
[/javascript]<br />
別の方法として、<br />
[javascript gutter="false" toolbar="false"]<br />
var va = (color32 >> 24) &#038; 0xff;<br />
[/javascript]<br />
とすることもできますが、シフト＋マスクの2演算よりも、符号無し右シフト1回の方が処理が速いと思います。</p>
<p>・・・ここまで書いていてふと思ったのですが、よく、ActionScriptの解説系サイトで、2の累乗で割る時は右シフト(&gt;&gt;)を使いましょうと書かれている事があるのですけど、値が0&#215;80000000よりも大きい場合には符号がひっくり返るんじゃないでしょうか。<br />
[javascript gutter="false" toolbar="false"]<br />
var a:Number = 2147483649; // = 0&#215;80000001<br />
var b:Number = a / 2;<br />
var c:Number = a >> 1;<br />
var d:Number = a >>> 1;<br />
var e:Number = a + c;<br />
var f:Number = a + d;<br />
trace(&#8220;a = &#8221; + a);<br />
trace(&#8220;b(a/2) = &#8221; + b);<br />
trace(&#8220;c(a>>1) = &#8221; + c);<br />
trace(&#8220;d(a>>>1) = &#8221; + d);<br />
trace(&#8220;e(a+c) = &#8221; + e);<br />
trace(&#8220;f(a+d) = &#8221; + f);<br />
[/javascript]<br />
実行結果は<br />
<code><br />
a = 2147483649<br />
b(a/2) = 1073741824.5<br />
c(a>>1) = -1073741824<br />
d(a>>>1) = 1073741824<br />
e(a+c) = 1073741825<br />
f(a+d) = 3221225473<br />
</code><br />
やはり、マイナスになりますね。<br />
わかっていて計算している分にはいいですし、こんな大きな値を使う事ってあまりないのでほとんど問題にならないと思いますが。だからといって、全部が全部、&gt;&gt;の代わりに&gt;&gt;&gt;を使って計算すればいいのかというとそうではないのですね。<br />
[javascript gutter="false" toolbar="false"]<br />
var g:Number = -100;<br />
trace(g);<br />
trace(g >> 1);<br />
trace(g >>> 1);<br />
[/javascript]<br />
<code><br />
-100<br />
-50<br />
2147483598<br />
</code></p>
<p>さてと、じゃあちょっと今から、838861枚のコインを買ってきますね。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.retropc.net/mm/archives/48/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

