ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年4月28日(日) 04:36

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 5 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年6月10日(金) 15:58 
Dim d0 As Long, d1 As Long, d2 As Long, d3 As Long, d4 As Long, d5 As Long
d0=98765
d1=Int(d0/10000) ' 9
d2=Int((d0-(d1*10000))/1000) ' 8
d3=Int((d0-((d1*10000)+(d2*1000)))/100) ' 7
d4=Int((d0-((d1*10000)+(d2*1000)+(d3*100)))/10) ' 6
d5=d0-((d1*10000)+(d2*1000)+(d3*100)+(d4*10)) ' 5
MessageBox(0,Str$(d1)+":"+Str$(d2)+":"+Str$(d3)+":"+Str$(d4)+":"+Str$(d5),"表示テスト",MB_OK)


通報する
ページトップ
   
投稿記事Posted: 2005年6月10日(金) 21:07 
オフライン

登録日時: 2005年5月31日(火) 20:14
記事: 203
お住まい: 兵庫県
件名が「長すぎる」と怒られたので、勝手に変えさせていただきました(^^;
コード:
Dim d0 As Long,d1 As Long,d2 As Long,d3 As Long,d4 As Long,d5 As Long
    d0=98765
    d1=d0\10000            ' 9
    d2=(d0 Mod 10000)\1000 ' 8
    d3=(d0 Mod 1000)\100   ' 7
    d4=(d0 Mod 100)\10     ' 6
    d5=d0 Mod 10           ' 5
    MessageBox(0,Str$(d1)+":"+Str$(d2)+":"+Str$(d3)+":"+Str$(d4)+":"+Str$(d5),"表示テスト",MB_OK)
こんな感じでどうでしょうか?
高速になったかどうかは謎です(汗)が、読みやすくはなったと思います。


通報する
ページトップ
投稿記事Posted: 2005年6月10日(金) 23:56 
余り計算が理解できます、この方法が通常は一番早いと思います。
超高速演算でする時は*、÷、÷の余り、は使えません。
(コプロセッサーの内部演算)
しかし一番良い方法だと思います。
囲碁と将棋の回答を出すので超高速でないと出来ません、悩んでいます。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2005年6月11日(土) 04:28 
オフライン

登録日時: 2005年5月31日(火) 07:49
記事: 162
これまでのiwaoさんの書き込みから判断すると、アセンブリ言語にも精通されている方のように思います。
アセンブリ言語を利用すれば、更に高速な処理を記述できます。
もしかしたら、既にご存知かもしれません。そのときはご容赦ください。

BCDをご存知でしょうか。Binary Coded Decimal(2進化10進数)といいます。
これはメモリ効率が悪いデータ形式ですが、今回のような処理にはもってこいです。
というか、これ以外に使い道があるのかどうか、疑問です。だれかご存知の方いらっしゃいます?
初めてBCDを知ったとき「○ンテルはどうしてこんな命令組み込んだんだろう」と首を傾げてしまいました(爆)
それは置いといて、、、
CPUの命令だから動作速度は最速(のハズ)です。また、除算を必要としません。
(ただし動作速度については検証しておりません。悪しからず。)

BCDは次のようなフォーマットです。
引用:
2進化10進数(BCD整数)は、範囲0~9の有効値を持つ符号なし4ビット整数である。
IA-32アーキテクチャは、1つ以上の汎用レジスタ内または1つ以上のx87 FPUレジスタ内にあるBCD整数の演算を定義している。

『IA-32 インテル アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル 上巻:基本アーキテクチャ(資料番号 253665-013J)第4章 データ型』より引用
簡単に言えば、10進数の一桁を表現するために4ビット使う、ということです。
例えば、10進数の52をBCDで表現すると、0x52となります。
x87 FPUレジスタは1つあたり10バイトの容量を持ちます。
先頭のバイトは符号バイトとして扱われるので、実質9バイトが利用できます。
ビットに換算すると72ビット、一桁4ビットだから、72÷4=18桁の10進数をBCDで表現できます。

この命令を利用する意義は大きいはずです。
こんな感じでいいとおもいます。
コード:
unsigned int i = 98765;    // 元の整数
unsigned char bcd[10];     // BCD整数を格納するバッファ
char d[18];                // 各桁の値を格納する配列  d[k]は 10 ^ k の位の値を保持する

int n;

__asm {

	fild    i
	fbstp   bcd

}

for(n = 0; n < 9; n++) {
	d[n * 2]     =  bcd[n] & 0x0F;
	d[n * 2 + 1] = (bcd[n] & 0xF0) >> 4;
}
FILDは整数をST(0)にロードする命令のニーモニック
FBSTPはST(0)をBCD形式に変換してストアしたあと、STをポップする命令のニーモニック

このアルゴリズムをDLL化するとよいとおもいます。
さすがに、コードの切れ端や実践コードモジュールに掲載できる程度を逸脱してしまいましたが・・・



[追記]
6月11日 12:18
上記コードは汎用形ですが、次のような無駄もあります。
  • forループ内で乗算を2回行っている
  • Long型の最大値は +2,147,483,647 であり、18桁を下回る
このような観点から、次のように最適化できます。
コード:
int n2;
for(n = 0; n < 5; n++) {    // 下位10桁を有効に扱えるよう、カウンタを調整
    n2 = n << 1;    // 2倍にはシフト演算を利用
    d[n2] =  bcd[n] & 0x0F;
    n2++;
    d[n2] = (bcd[n] & 0xF0) >> 4;
}


最後に編集したユーザー tak [ 2005年6月11日(土) 12:18 ], 累計 1 回

通報する
ページトップ
投稿記事Posted: 2005年6月11日(土) 07:48 
fildとfbstpは私はまだ使ったことがありません、これを見て作れるようになりました。インテルやペンティアムだけ使える、便利なコードもあるのはご存知だと思います(発表していないうらもあります)、通常はOSが同じ利用なので切り分けるのが難しく利用しませんが、このコードはどちらでも使えるコードで良いと思います。私はコンパイラーが一番好きでABを使用させてもらい処理で遅くなる命令や関数をよく作りDLLに置き換えします、CPUを識別させて他のよい機械語を利用することも考えます。私は何でもスクリプトを一番適切でよい、早い処理、一番よい式、で作らないと楽な生活が出来なくなります、私は遅れても前もって準備しながら一番先端に行けるように考えます、自分の能力が後れれば会社に出勤する大変な生活にはなりたくありません、そのため私に無駄な内容が多いときは遠慮しますが、内容が深く感謝します。


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 5 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[17人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean