Archive for 8th 6月 2009

風と共に去りぬ(3)

やっとのことで故郷タラにたどりついたスカーレットとアトランタから戻った一向だが、
母エレンは死に、そのせいで父ジェラルドも廃人となってしまった。

戦前のように何もせずにいれば食物も手に入らない状況の中、スカーレットはいくつもの課題を解決していくが、北軍の統制によって課せられた農園の土地の税金300ドルを払う手段がどうしても見つからない所に、たんまり儲けたといわれるレットバトラーが北軍の刑務所に入れられていることを知った。

以前、レットに「情婦になれ」ということを問われて激怒した過去があったが、それを利用してレットの財産を狙おうとするがレットに策を見破られて断念する。

そこにいずれスカーレットの妹スエレンと結構することになるであろうフランク・ケネディと偶然会う。フランクの商売が順調なのを知ると、スカーレットはフランクの財産狙いに彼と結婚することを画策した。

現代で言えばスカーレットばかりひどい目に逢っているが、その分成長していると言えるが、当時の社会では女性がそのように効率よくことをこなすという事が認められない。(逆に非難される)時代であった。
ここでこのような描写が当時どのように受け入れられたのか?


シフト演算

論理演算の基本の続きです。

もう見た感じだけじゃなんだかわからないのがシフト演算です。
対象は整数のみですが、これをビットに変換して、その形状?を保ったまま
右や左に動かしたのがその結果となります。

例えば、255(二進数で11111111)を左に4ビットシフトする場合は以下のように記載します。

255 << 4

実際やってみると以下のようになります。

//実行例
System.out.println(
			  Integer.toBinaryString(255) +  "(255) << 4 = "
			+ Integer.toBinaryString(255 << 4)
			+  "(" + (255 << 4) + ")");
//結果
11111111(255) << 4 = 111111110000(4080)

右の下位桁に0が4桁分追加されています。

今度は、同じく255を右に4ビットシフトする場合はこうなります。

//実行例
System.out.println(
		  Integer.toBinaryString(255) +  "(255) >> 4 = "
		+ Integer.toBinaryString(255 >> 4)
		+  "(" + (255 >> 4) + ")");
 
//結果
11111111(255) >> 4 = 1111(15)

右に4桁移動しています。移動した際、右から4桁分は切り捨てられます。
同じように左シフトの場合もあふれた分は切り捨てられます。

//実行例
System.out.println(
		  Integer.toBinaryString(1431655765) +  "(1431655765) << 4 = "
		+ Integer.toBinaryString(1431655765 << 4)
		+  "(" + (1431655765) + ")");
//結果
1010101010101010101010101010101(1431655765) << 4 = 1010101010101010101010101010000(1431655760)

この例は溢れた分があるので元の値より結果が小さくなっていますが、
基本的には、左シフトした場合は2シフトしたビット数倍、
右シフトの場合は2シフトしたビット数分の1倍になります。

値がマイナスの場合も基本的には同様です。

//実行例
System.out.println(
		  Integer.toBinaryString(-255) +  "(-255) << 4 = "
		+ Integer.toBinaryString(-255 << 4)
		+  "(" + (-255 << 4 = "
		+ Integer.toBinaryString(-255 << 4)
		+  "(" + (-255 << 4) + ")");
//結果
11111111111111111111111100000001(-255) << 4 = 11111111111111111111111111110000(-16)

ここで右シフトしている場合、正数と違うのが、1をシフトした分だけ補完しているということです。
Javaの場合は、上位1bitプラス・マイナスの符号を保持していますが、
上記の右シフト演算の場合、その符号の値を右から補完します。
このシフト演算を「算術シフト演算」といいます。

「算術シフト演算」のほかにシフト演算があるのか?というとあります。
算術シフト演算で右シフトした時に上位ビットを補完する値は符号の値と言いましたが、
これを常にゼロで補完するやり方があります。これを「論理右シフト演算」という言います。
表記方法は、「>>>」のように「>」を3つ書きます。

(StringUtilsで上位桁を0で埋めて表示しました)

//実行例
System.out.println(
		 org.apache.commons.lang.StringUtils.leftPad(Integer.toBinaryString(-255), 32, "0") 
		+  "(-255) >> 4 = "
		+  org.apache.commons.lang.StringUtils.leftPad(Integer.toBinaryString(-255 >> 4), 32, "0") 
		+  "(" + (-255 >> 4) + ")");
System.out.println(
		 org.apache.commons.lang.StringUtils.leftPad(Integer.toBinaryString(-255), 32, "0") 
		+  "(-255) >>> 4 = "
		+  org.apache.commons.lang.StringUtils.leftPad(Integer.toBinaryString(-255 >>> 4), 32, "0") 
		+  "(" + (-255 >>> 4) + ")");
//結果
11111111111111111111111100000001(-255) >> 4 = 11111111111111111111111111110000(-16)
11111111111111111111111100000001(-255) >>> 4 = 00001111111111111111111111110000(268435440)

上記の結果のように、論理右シフト演算の場合は0で上位桁が補完されていることが分かります。
ちなみに、「論理左シフト演算」はありません。
だって右から1が補完されてしまうとまったく別の値になってしまいます。
と思って一応ググってみたら
そんな場合もあるんですね。