2010/05/17(月)省電力マシンで Ubuntu 10.04 Server セットアップメモ

2010/05/14(金)3の倍数を除算せずに判定する

テーブルが間違ってたバグを修正しました(汗) 感謝>ingktさん


3の倍数を除算を使わずに判定したいという話を聞いたので、ちょっと考えてみました。

方法

2進数表示を考えて2桁ごとに区切ります。それぞれ0~3までの数字と捉えて、足し算します。足し算の結果が3で割り切れれば3の倍数です。

372 → 101110100b
 → 1b + 01b + 11b + 01b + 00b
 = 1 + 1 + 3 + 1 = 6

(参考にしたサイト) No.055 「111」は「3」の倍数(原理は一緒)

実装

intが32bitの場合(0-0xfffffffeまでテスト済)。

#define MUL3TABLE 0x49249248	// bit31 to 0
int mul3test(unsigned int x) {
	int i;
	int c=0;
	for(i=0; i<16; i++,x>>=2) {
		c += (x & 3);
	}
	if (c>30) c-=27;
	return (MUL3TABLE >> c) & 1;	// if multiple 3 return 1
}

16bitの場合。

#define MUL3TABLE 0x9248;	// bit15 to 0
int mul3test(unsigned int x) {
	int i;
	int c=0;
	for(i=0; i<16; i++,x>>=2) {
		c += (x & 3);
	}
	if (c>15) c-=12;
	return (MUL3TABLE >> c) & 1;	// if multiple 3 return 1
}
}

判定に0を含める場合

「3の倍数」ではなくて3で割り切れるかどうかを判定する場合は、

#define MUL3TABLE 0x49249248	// bit31 to 0
#define MUL3TABLE 0x9248;	// bit15 to 0

をそれぞれ、

#define MUL3TABLE 0x49249249	// bit31 to 0
#define MUL3TABLE 0x9249;	// bit15 to 0

と修正してください。

改良 2010/05/14

ts1さんのコメント通り改良したもの。

int mul3test2(unsigned int x) {
	x = ((x >> 2) & 0x33333333) + (x & 0x33333333);	// 0 to 6
	x = ((x >> 4) & 0x0f0f0f0f) + (x & 0x0f0f0f0f);	// 0 to 12
	x = ((x >> 8) & 0x00ff00ff) + (x & 0x00ff00ff);	// 0 to 24
	x = ((x >> 16) + x) & 0x0000003f;
	if (x>30) x-=27;
	return (MUL3TABLE >> x) & 1;	// if multiple 3 return 1
}

ingktさんの改良案。2bitずつ加算しなくてもいいのは気付かなかった(汗)

int mul3test3(unsigned int x) {
	x = ((x >> 4) & 0x0f0f0f0f) + (x & 0x0f0f0f0f);
	x = (x >> 8) + x;
	x = (x >> 16) + x;
	x = ((x >> 4) & 7) + (x & 0xf);
	return (MUL3TABLE >> x) & 1;
}

実行速度0~0xfffffffeまで。gcc -O3でコンパイル。

mu3test()
real    2m10.451s
user    2m10.400s
mu3test2()
real    1m28.912s
user    1m28.900s
mu3test3()
real    15.719s
user    15.700s

非力なマイコンだとしても、ingktさんの実装が一番スマートですね。

2010/05/01(土)2.4V→12V LT1308 ヘッドホンアンプ用昇圧回路

単3電池2本(特にニッケル水素)から12Vの電圧を得たいと要望があったので、色々無理はあるのですがLT1308でDCDCを作りました。

回路図

2010/07/09回路図、解説を更新

LT1308_2.4to12.png

出力電圧 = 1.22V + R1/R2*1.22V

部品表

部品番号部品解説
U1LT1308B昇圧DCDCコンバータ。
L1パワーコイル。10uH2Aぐらい流せるもの。
L2パワーコイル。47uH2Aぐらい流せるもの。
D1SBD。耐圧20V以上。SBDならなんでも。
C1,C3,C516V以上100uF電解コンデンサ低ESR推奨。
C2,C4積セラ10uFICになるべく近づけて実装
C6積セラ1uFフィルムコンでも可
C6フィルムコンデンサ1uF省略しても良い。積セラ不可。
C7積セラ100pF-
R1,R2適時-
R3100kΩ-

解説

  • 出力電圧は13.2V程度に設定されています。
  • コイルはパワーコイルを使用し、直列抵抗値の低いものを選んでください。よくわからなければ1~2A流せるものを選べば良いと思います。
  • L2は47~220uH程度で適当で構いません。あまり低いとノイズが除去しきれません。
  • C2,C4はなるべくICに近づけて実装。特にC2

入力側パスコンがとても重要です。できれば、C2に100uF/6.3V/X5Rなどのチップ積セラ(MLCC)を使用してください(100uFを付けるならC1は要らないでしょう)。もしくはC1にOS-CONを使用してICに近づける等。

この辺の配線処理が甘いと出力電圧が安定しませんし出力ノイズも増えます。SOP→DIP変換とか使うべきじゃないし、ICソケットなんてもっての他です。

LT1308とLT1308B

LT1308Bを入手できたので、比較してみました。

DCDC2次側のスイッチングノイズ。

LT1308LT1308B
osc-LT1308.jpg
osc-LT1308B.jpg

連続スイッチ(バーストモード動作)をするBは綺麗な繰り返し波形になっていますが、LT1308/LT1308Aは電圧の様子をみながらスイッチするためノイズ波形が複雑になっています。上記回路図のとおりきちんとLCフィルタしてるにもかかわらず、聴覚上はっきりとLT1308Bの方がよくなりました。

オーディオ用途にはバーストモードにすべしということが聴覚上確認できてました。予想どおりの結果です。