あまつぶ

12.3 1:30

 昨日1日のアクセス数が1046だったみたい。記録をとりはじめてからの新記録更新(^^)。どうもアクセスありがとう〜!!

 予定通りMathPadのXFunについて。サンプルがついているのでまずはこれをコンパイル……と思ったらCWで作られているんだけどプロジェクトのバージョンが古くてコンバートできない。IDEの1.7で一度開けということなのでCDをつっこんでCW11 IDE and Prefsというのを展開してなんとかコンバート。Pro3でしかチェックしていないけど他のバージョンでもおそらくついているはず。まあプロジェクト自体はそう複雑でもないから作り直してもそれほど手間じゃないけど。
 プロジェクトを開いてみると(ぼくはmodを開いた)ソースの他に「callback.c」というファイルが入っている。これがMathPadとやりとりする部分で、まあ使いそうな関数だけヘッダでチェックすればいいだろう。とりあえずは16進数を数字に変換する関数ということなので、文字列の読み込み方と値を返す方法さえわかれば十分だ。modには値を返す部分があるからここはそのまま流用すればよさそうだ。文字列の取得はGetParmNameという関数を使えばできるらしい。
 ソースの話に入る前に少しだけプロジェクトの説明をしておくと、コードリソースでクリエータはMPad、ファイルタイプはXFunにする。リソースタイプもXFunだ(PPCコードの場合はCFunらしいがこれついてはまた機会があれば)。IDはおそらくなんでもいいのかもしれないが、サンプルでは1になっていたし付属のものもだいたい1だったのでこれにあわせておくのが無難だろう。ドキュメントのどこかに書いてあるのだろうがまだチェックしていない。ま、コードリソースの作り方を知っている人なら別段難しいことはないかと思う。
 さて、ソース。mainはfunptr型の引数をとり、そこでAddXfunで関数を追加する。第一引数が関数の名前、第二引数が関数の引数のリスト(わかりにくい(笑))、第三引数が実際に呼んでもらう関数へのポインタで、残りはよく知らないけどとりあえずこうしておけばいいらしい。で、呼んでもらう関数の方は引数にdouble型へのポインタをとり、ここに結果を返す形になる。関数自体の返り値はなにを返すべきなのかいまいちよくわからないが、うまくいった場合はtrue、なにかおかしいときはfalseを返すということかも知れない。呼んでもらったらまず引数の文字列を取り出す。これにはGetParmNameを使うのだが最初の「0」は「一番」の引数を取り出す。なぜか左から順番ではなく右かららしいので注意。2つ目は文字列へのポインタを指定。ここに文字列が返ってくる。あとはそれを数字に変換して返してやればokと。具体的にはソースを見てもらうのが早いのでソースを掲載。

/* HexToDec.c */

#include	"callback.h"

#define	h2d(c)	((c>='0' && c<='9') ? c-'0' : ((c>='A' && c<='F') ? \
			c-'A'+10 : ((c>='a' && c<='f') ? c-'a'+10 : 0)))


static short	HexToDec(double *retval,funptr callback);
static long		HtoDMain(char *hex,long l);

short main(funptr callback)
{
	AddXfun("HtoD","hex",&HexToDec,nil,callback);
	
	return 0;
}

static short HexToDec(double *retval,funptr callback)
{
	short	ok;
	char	*hex;
	
	ok = GetParmName(0,&hex,callback);
	
	if (ok) *retval=(double)HtoDMain(hex,0);
	
	return ok;
}

static long HtoDMain(char *hex,long l)
{
	if (*hex==0) return l;
	return HtoDMain(hex+1,l*16+h2d(*hex));
}


 最初に気色の悪いマクロがあったりするが気にしないでいただきたい(苦笑)。横幅が長過ぎるので途中に「\」(欧文フォントではバックスラッシュ)を入れてある。defineで長いマクロを作りたい時にはこれで改行を挟むことができるんだそうな。今回初めて知った(笑)。このマクロは見ればわかるとおり文字を16進数とみなして10進数に変換しているだけ。なんでこんな方法を使ったかというと、、単にやってみたかっただけ(笑)。
 このマクロだけでは1文字しか変換できないので一番下にあるHtoDMainで文字列から変換するようになっている。ここもなんか再帰呼び出しを使っていたりして気持ち悪いけど、ここも細かいことは気にしてはいけない。それから16進数に使える文字以外が含まれていた場合のことをなにも考えていないので"5%"とかを渡すと80が返ってきたりする(要は"50"と解釈)。本当はエラーを返すようにするべきなのだろうが方法がわからないので省略(汗)。ヘッダを見るとErrMsgという関数があるようなのでおそらくこれでできるんだろうとは思うが。
 これでまあ「HtoD("64")」とやれば「100.000」が返ってくるようになったのだが、この逆は……無理っぽい。エラーメッセージとして表示とかいうイレギュラーな方法を使えば可能かも知れないがおそらく普通に文字列を返す方法はなさそうだ。そもそも計算するのが目的なんだから文字列を出力してもしかたないもんなぁ。あと、関数名や変数名は大文字小文字を区別するので「HtoD」にしたら「htod」とかでは動かない。使い勝手を考えると小文字にした方がまだ使いやすいかも知れない。また文字列の指定部分だが、変数として使用していないものであれば例えば「HtoD(ab)」でも「HtoD(a5)」でも正しい結果が得られる。数字とみなされてしまう「HtoD(1)」などは無効になる。「HtoD(1a)」などもエラーになる。まあ""で括ってやるのが確実だろう。それから関数の名前だがひょっとしたら$("10")とかできないかなと思ってやってみたがこれも無理なようだ。

 MathPadの話はこのくらいにして(しかしほんとに多機能で奥が深いので日本語のドキュメントでも誰かが作れば普及しそうなんだけど、、ってどこかにありそうな気もしつつ)理想の電卓の続き。もちろんぼくにとっての「理想」であって他の人にはまた別な理想があると思うんだけど、16進数は「$」をつけて指定、特に指定がなければ16進数とみなされ、10進数は「#」をつけてあらわすというMacsBugの書式がうれしい(笑)(指定がなかったときどちらにされるかってのは選べる方がいいけど……、AAとかならもちろん16進数だと自動判断するのは当然)。それから計算結果は16進数と10進数で並記されるのがベストかな。小数部分はどうするんだって気もしつつ、小数計算もできる16進数電卓なんていうのもあってもいいような気がする(いらんか)。例えば16進数で円周率をあらわしたら3.243F6A8...なぞに、、してどうする(笑)。そういえば前に書いた「数の辞典」って本では2進数で書いた円周率と自然対数の底eが表紙と裏表紙にずらーーっとかかれていたっけ。あれもなにも知らずに見たら0と1がランダムに並んでいるだけだもんな〜(笑)。
 あれ、話がそれた。理想の電卓の話。16進の小数計算はどうでもいいとして、こんな電卓あるといいなぁ。MacsBugを超えてくれ、頼む……(なんじゃそりゃ)。ま、まずは16進数も含めて括弧と四則演算でできた計算式を計算するプログラムを書くところから、かな? はいぱかだったら式の中から16進数の部分を探してそこを10進数に変換してやって「value of ...」で一発だったりするんだけど。

 IconPartyがなぜかフリーズするバグについて……。またいくつかバグを見つけて修正したのだがどうにもフリーズする。しかも、デバッグ用のアプリケーションではフリーズしないみたいなのに完成(&公開)用のアプリケーションではフリーズする。これはひょっとしたらプロジェクトの設定の違いかも知れないと思いチェックしてみたところ、どうも「PC-Relative Strings」をチェックするとフリーズしないらしい。、、な、なんでや?? コードリソースでソース中に文字列を埋め込んでいる場合ならともかく、普通のアプリケーションでは関係ないのでは……。これまでも特に気にしたことはないし、おそらくどこかまずい部分があってここにチェックするとたまたま回避できているということだろうと思うがこれは厄介な問題かも知れない。
 あ、でも……、「PC-Relative Strings」にチェックを入れていない時はDATAリソースに文字列をつっこんでいるんだよな。ってことはここをチェックしに行く時におかしくなっていると仮定すると、カレントリソースファイルの設定がうまくいってないのかも。そう思っていろいろ見てみたのだが、どうもCurResFileを呼んだ時にアプリケーションの参照番号が返って来ていないことがあるみたいで、、。しかたないのでLDEFを書き換えてアプリケーションの参照番号をLDEFに渡すようにしてみたらなんとかうまくいけたみたい。よかったよかった。
 そんなわけでこれからサイズ変更やら倍率変更のルーチンを書くっす〜。週末までに0.20b1をリリースの予定!! お楽しみに〜。
 9:30

 Geneva2Osaka 1.00b14での速度低下について。結構違いが出ているいうメールをいただいたので(ありがとうございます>飯泉さん)、うちの環境(PowerMacG3 DT233)でGeneva2Osakaを入れていない状態、b12.2を入れた状態、b14を入れた状態でどのくらい速度が違うかをMacBench 4.0を使ってテストしてみた。MacBenchの最新バージョンはたしか5.0だったような気もするけどすぐに手に入れられたものが4.0だったので……。まあそれほど変わりはないだろうということで細かいことは気にしないことにしよう。
 それぞれ一度ずつしか試していないのでどの程度信頼のおけるデータかはなんとも言えないが、b12.2、b14とも、QuickDrawの描画ルーチンでの速度低下はほとんど見られなかった。入れていない状態を100として一番遅くなったもので99.11というのがあるが、誤差の範囲内だろう。中には100.89なんていうものもあったし。b12.2とb14の比較でもb12.2を100として99.12〜100.58であり、全体的にほんの少しの速度低下はあるようではあるが思っていたほどの差はないような感じだ。
 で、問題はテキスト表示ルーチンで、b12.2では入れていない状態を100としてDrawChar 90.99、DrawString 92.91、DrawText 99.28だったのに対し、b14では95.78、81.67、85.04という結果になった。DrawCharでは速度が若干向上しているがDrawStringやDrawTextではかなり大きく低下しているのがわかる(それぞれ12.1%、14.34%の低下)。体感的にはほとんどわからないとはいえ、こうやってはっきりとしたデータとして示されるとやはり気になってしまう。そんなわけでこれらのルーチンに対し、速度向上を試みてみた。
 ニューバージョンを作成しそれでテストしてみたところ、入れていない状態に対して、95.46、105.12、99.98という結果が得られた。これはb14に比較するとそれぞれ99.67、128.71、117.56であり、b12.2に対しても104.91、113.14、100.70と、若干の速度向上が実現できた。もう少しテストしてから公開予定だが、売り文句は「b14に比べて最大29%、b12.2に比べても最大13%の速度向上」であろうことは言うまでもない(笑)。ま、これもおそらく体感的には全く変わらないであろうとは思うが。
 一応念のために(?)うちでテストした結果をテキスト化したものを読むことができるようにしておこう。タブ区切りのテキストになっているので表計算ソフトなどで読み込むと見やすいかと思う(というかもとのデータはクラリスワークスで作成したのだが)。→テスト結果
 68k版についても同じようにおそらく速度向上しているはずだが、これはベンチマークができる環境がないのでちょっとわからない。うちにある68kマシンはPowerBook145Bのみで、メモリが8MではMacBenchが動かないのだ(笑)。もっと小規模なベンチマークプログラムがあるといいのだが、なにかいいのないかなぁ。テキスト関係の部分だけでいいから自分でちょっと作ってみるという手もありつつ……。

to December 2, 1998 ↑ to December index → to December 4, 1998