ちょっとしたテクニークスレッド

このエントリーをはてなブックマークに追加
1名無しさん@お腹いっぱい。
if( hogehoge == 1 )

if( 1 == hogehoge )
と書くと、イコールが一個しかなかったときエラーに
なってくれる。

#罵倒をおそれずかきこめー
2>1:2000/08/21(月) 16:02
その話題ふると 恐い人がやってくるのでsageですぅ
3名無しさん@お腹いっぱい。:2000/08/21(月) 17:42
(define (dbg x . s) (for-each display s) (display x) (newline) x)
4名無しさん@お腹いっぱい。:2000/08/21(月) 17:43
つーか、1(最初の文章)に
>#罵倒をおそれずかきこめー
だけ書いて
2に内容書けばよかったのに・・・


struct hoge {
  char *ptr;
  char str[1];
};
C++だと使いにくいが…
5名無しさん@お腹いっぱい。:2000/08/21(月) 18:26
VC++だと
struct hoge{
 char *ptr;
 char str[0];
}
が出きるから、それに慣れてたせいでgccに移植するときに泣いたことが…
6名無しさん@お腹いっぱい。:2000/08/21(月) 21:48
>4@`5
それって何に使うんですか?純粋に知りたいです。
74:2000/08/21(月) 22:09
つい、例にポインタをいれてしまったので、わかりにくいか。

例えば、文字列のリスト構造を実現する場合に
リストを実現する構造体と、文字列を記憶する配列分の
2回、mallocを呼ぶ必要がある。
ところが、4の形式、つまり構造体の最後のメンバにchar[1]があると、
 p = malloc(sizeof(struct hoge)+strlen(s));
 strcpy(p->str@` s);
という技が使える。
利点はmallocの呼び出し回数が減らせるため、
記憶領域的にも速度的にも有利になる。

もちろん、charに限らず、
「不定長の領域を本体とは別に確保する必要がある場合」に、
使う事が出来る。
8:2000/08/21(月) 23:41
誰も上げないので
あげ
9>6:2000/08/22(火) 00:02
構造体の最後のメンバが可変長のデータを持っている(指しているのではない)
の時に使います。
とくに、生成から消滅までの間固定長だけど、モノによってデータサイズが違う
ときに有効です。
10名無しさん@お腹いっぱい。:2000/08/22(火) 01:50
Shift-JIS 漢字第一バイトの判定

if ( ((c >= 0x81) && (c <= 0x9F)) || ((c >= 0xE0) && (c <= 0xFC)) )

のかわりに

if ( (c >= 0x81) && ( (c <= 0x9F) || ((c >= 0xE0) && (c <= 0xFC)) ) )

の方が、多くの場合速度が速いコードが作れ、オーバーヘッドもほとんどない。
括弧が多いのは、今書いたからなんで、かんべん。

11このスレおもしろいかも:2000/08/22(火) 02:00
//1と2を入れ替える
i := (i - 1) * (-1) + 2;
{
if i = 1 then
 i := 2
eles
 i := 1;
}
2つもコメントを入れてしまった俺は根性なし・・・
12名無しさん@お腹いっぱい。:2000/08/22(火) 02:03
<10
2つ以上の範囲の判定なら、いつでも使えそうですね。
13名無しさん@お腹いっぱい。:2000/08/22(火) 10:13
VBでCombo boxにリストを追加したい時、普通は
Combo1.AddItem リスト項目
とやる。
が、この項目がうん百件とある場合(データベースから拾ってくる等)
AddItemでは偉く時間がかかってしまう。
そこで、APIを使うと速度が向上する。
こんな感じだ。
あらかじめ、Option Explicitで以下のように宣言しておく。

Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long@` _
ByVal wMsg As Long@` _
ByVal wParam As Long@` _
ByVal lParam As Any) As Long

で、実際の処理部分は、
自分の場合DBにオラクルを使ったので、

Dim ret As Long
Dim cbHwnd As Long
Dim cbitem As String
Dim SQL_TEXT As String

cbHwnd = Combo1.hwnd
Combo1.Clear

SQL_TEXT = "select hoge from TB_hoge "
SQL_TEXT = SQL_TEXT & "where code = 'hoge'"
SQL_TEXT = SQL_TEXT & " ORDER BY hoge"
Set OraDs = OraDatabase.CreateDynaset(SQL_TEXT@` ORADYN_READONLY)

OraDs.MoveFirst
Do Until OraDs.EOF
cbitem = OraDs![hoge] & vbNullString
ret = SendMessage(cbHwnd@` CB_ADDSTRING@` 0@` cbitem)
OraDs.MoveNext
Loop

といった感じになる。
かなりスピードアップするハズ。
お試しアレ。
sendmessageは奥深いよ……。
14名無しさん@お腹いっぱい。:2000/08/22(火) 11:22
常識かもしらんけど。

#define SWAP(a@`b) (a^=b@`b^=a@`a^=b)
15>11:2000/08/22(火) 11:26
i = (1+2) - i;
でええんとちゃうの?
BASIC時代にはしょっちゅう使ったテクだが。
16名無しさん@お腹いっぱい。:2000/08/22(火) 11:40
>15
つーか、それって3-i
17名無しさん@お腹いっぱい。:2000/08/22(火) 12:21
有名かもしれんが、

printf("%0*d\n"@` 4@` 123 );


186:2000/08/22(火) 12:26
>7@` 9
なるほど〜。
WinAPIでパレットいじるときのあれみたいなものですね〜。
どうもありがとうございました。
19>13:2000/08/22(火) 13:42
それ以前に
COMBOやMSFLEXGRIDなんかは

Combo1.Visible = False

処理

Combo1.Visible = True

とするとオーバーヘッドが発生するはずなのになぜかかなりの高速化になる。
20名無しさん@お腹いっぱい。:2000/08/22(火) 15:07
LD BC@`DEを実現する
PUSH DE
POP BC
21名無しさん@お腹いっぱい。:2000/08/22(火) 16:13
ALの符号をAHに拡張する
CBW
22>20:2000/08/22(火) 17:56
mov b@` d
mov c@` e
でいいと思うんだけど。なぜにスタックを使う?
メモリを介さない分、速いだろうとおもうのですが。
2320:2000/08/22(火) 18:30
>>22
??言われてみれば、そうだな……。Z80の話だからなあ。
よく覚えてねえや。
じゃあ、これでどうだ
XCHG BC DE を実現する
PUSH BC
PUSH DE
POP BC
POP DE
24名無しさん@お腹いっぱい。:2000/08/22(火) 20:06
inline int IsShiftJIS(unsigned char c)
{
 if(c>=0x81)
 {
  if(c<=0x9F)
   return 1;
  else
  {
   c += 0x20;
   if(c <= 0x1C)
    return 1;
  }
 }
 return 0;
}

こう言うのはやっぱり無駄な努力なんでしょうか。
25!=22:2000/08/22(火) 20:09
どうだ、って、それもaを使って6回LDする方が速いんじゃねーの?
2620:2000/08/22(火) 21:08
>>25
かな?
まあ、アキュムレータを使わないでも済む方法、ってことで一つ……。
どっちが早いかは、今手元に資料が無いから分かんないよ。
27!=22@`25 :2000/08/26(土) 04:58
8ビット汎用レジスタ間LDは全部4クロック、PUSH/POPは11+10クロック
だから、スタックは使わない方が基本的に速い。
23のはAレジスタ使わないなら
PUSH BC
LD B@`D
LD C@`E
POP DE
あたりで妥協かな。
28名無しさん@お腹いっぱい。:2000/10/31(火) 19:12
ageてみよう
29名無しさん@お腹いっぱい。:2000/10/31(火) 19:23
>>14
逆の意味で常識。
SWAP(x@` x);
とした場合、何が起こる?
30名無しさん@お腹いっぱい。:2000/10/31(火) 19:34
0と1を入れ替え。

int a = 0;
a = 1 - a;

すげーだろー。
31名無しさん@お腹いっぱい。:2000/10/31(火) 19:48
>30
a^=1; でええやん。

32名無しさん@お腹いっぱい。:2000/10/31(火) 21:37
人差し指と薬指で広げておいて、中指を膣口に忍ばせ、
更に親指はクリトリスを責める!
33名無しさん@お腹いっぱい。:2000/10/31(火) 21:39
0からN-1までをなめるとき、
for (int i = N - 1; i >= 0; --i) {
...
}
みたいに判定を0で行うとほんの少し速くなるかも
#こんなこと気にしながらプログラム書きたくないけど・・・
34ミトコンドリ子:2000/10/31(火) 21:52
アタシはこっちの書き方のほうが好きよ。
for ( int i=N ; --i >= 0 ; ) {...}
Nの表記が長いときに -1 が紛らわしくならないからよ。

0比較のため、というよりはインデックス逆巡回を書くときの
イディオムよね。
35名無しさん@お腹いっぱい。:2000/10/31(火) 22:05
>>33@`>>34
境界判定のための比較が要らなくなるか、
って、アセンブラなら減産して0だった時点でZeroフラグ立つよね。

Cって、
オプティマイズされたオブジェクトなら、意外な方法で高速にしたりするんで、意味無し!

3633:2000/10/31(火) 22:10
>>34
>for ( int i=N ; --i >= 0 ; ) {...}
あ、、、きれい・・・いただきます:-)

>0比較のため、というよりはインデックス逆巡回を書くときの
>イディオムよね。
んーでも、比較すべき数値をレジスタにロードしなくて良い分
速いかなぁと・・・CPUによりけりですけど。
おまじないのように上記のようにがんばって書いてました。
「もうちょっと速くなりますように」とお祈りしながら・・・
3733:2000/10/31(火) 22:19
>>35
>Cって、
>オプティマイズされたオブジェクトなら、意外な方法で高速にしたりするんで、意味無し!
いや、先の例で、Nが変数のときには
for (int i=0; i < N; ++i) {...}
で、比較部分がほんのちょこっとだけ最適化あまくなるようなきがしません?
まあ、目に見えて速くなるわけではないですが、
藁にもすがりたいときにはおまじないとしてやってます。。。
だめっすかねぇ・・・
38名無しさん@お腹いっぱい。:2000/10/31(火) 23:33
for ( int i=N ; --i >= 0 ; ) {...}  って
for ( int i=N ; i-- ; ) {...} でも可?
39名無しさん@お腹いっぱい。:2000/10/31(火) 23:41
x+=(button==RIGHT)-(button==LEFT);
y+=(button==UP)-(button==DOWN);
(;´Д`)
40名無しさん@お腹いっぱい。:2000/11/01(水) 00:01
すんません
ここの人はアセンブラとかにも詳しいのかな?
便乗質問させてください。

for(int i=N; --i;){}

int i=N;
while(i--){}
ではforの方が早くなるんですか?

最適化のあまりよろしく無いコンパイラ(あまり最適化に頼るのもなんなので)
普通程度の最適化がなされるコンパイラ(今時のコンパイラならそのぐらい基本的みたいな)

の両方のケースで教えてください。
41名無しさん@お腹いっぱい。:2000/11/01(水) 00:12
>>40
何故自分で確かめない?
42名無しさん@お腹いっぱい。:2000/11/01(水) 00:35
x=y=z=0;
(;´Д`)
43名無しさん@お腹いっぱい。:2000/11/01(水) 00:40
>>40
ループ回数違うような・・・
あと、iが0になったかどうかだけで判定してますが
Nが負で渡ってきちゃったときとか不安・・・
iのスコープも違ってるし・・・

スピードは同じっぽそう。逆アセンブルして確かめよう。
44名無しさん@お腹いっぱい。:2000/11/01(水) 00:46
自分の目で確かめろ。
アゲてるやつはみんな白痴。
45名無しさん@お腹いっぱい。:2000/11/01(水) 01:24
他人を白痴呼ばわりするのって楽しい?
46名無しさん@お腹いっぱい。:2000/11/01(水) 02:15
>>45
あなたは、そんなこと聞いてどうするの?
47名無しさん@お腹いっぱい。:2000/11/01(水) 02:29
int a@`b@`c;
....;
if(int d=a-b)
{
d+=...;
c+=d;
}
(;´Д`)
48名無しさん@お腹いっぱい。:2000/11/01(水) 05:39
何これ?>47
49名無しさん@お腹いっぱい。:2000/11/01(水) 13:04
>>45
たのしぃでぇ〜す。

酔っぱらい関数きぼん。
50名無しさん@お腹いっぱい。:2000/11/01(水) 15:12
ここおもろい!!わしもかきこ!!

nビットのマスク生成

(1 << n) - 1;
51名無しさん@お腹いっぱい。:2000/11/01(水) 23:09
あらら、sageばっかり・・・
あげちゃえ!
52名無しさん@お腹いっぱい。:2000/11/02(木) 00:07
mvi a@`0
ではなく
xra a
とすると1バイトで済む

メモリを0(等)で埋める歳にはpushを使うと速い

dadで16bitの引き算をするには…
bcとdeをxchgしたい時には…
は当たり前の事か
53名無しさん@お腹いっぱい。:2000/11/02(木) 00:26
bool light0;
…;
(light0?Enable:Disable)(LIGHTING);
(;´Д`)
54名無しさん@お腹いっぱい。:2000/11/02(木) 00:35
CMP AL@`0Ah
SBB AL@`69h
DAS

5バイトの1桁16進バイナリ−ASCII文字変換。
有名だねー。
55名無しさん@お腹いっぱい。:2000/11/02(木) 00:46
CLEAR @`&HBFFFしないでGVRAMにアクセスするルーチンをC000以前に置くには
文字列変数に入れてVARPTR()の値を参考に絶対アドレスの部分を書き換える

って何の話だ
56名無しさん@お腹いっぱい。:2000/11/02(木) 03:03

SJIS2JIS PROC
     sub al@`71h
     and al@`3Fh
     stc
     rcl al@`1
     cmp ah@`7Fh
     cmc
     sbb ah@`1Fh
     cmp ah@`7Fh
     jc @skp
     inc ax
     sub ah@`7Fh-21h
@skp:
     xchg al@`ah
     ret
SJIS2JIS ENDP
57名無しさん@お腹いっぱい。:2000/11/02(木) 04:17
typedef unsigned char BYTE;
typedef struct { BYTE stuff[100]; } BYTE100;

*(BYTE100*)px = *(BYTE100*)py; //memcpy(px@`py@`100)と同じ?
58名無しさん@お腹いっぱい。:2000/11/02(木) 05:05
>>56
よかったらJIS2SJISも書いてくださ〜い。
59名無しさん@お腹いっぱい。:2000/11/02(木) 09:48
int c の b ビット目の on / off

#define BITon(b@`c)  ((c) = ((c)|(0x01<<(b))))
#define BIToff(b@`c)  ((c) = (~(~(c)|(0x01<<(b)))))

ダサイ???
60名無しさん@お腹いっぱい。:2000/11/02(木) 18:46
#define BIToff(b@`c) ((c) = (c) & ~(1 << (b)))
c++ を無意識に使う怖さから、inline にしたほうがいいと思うが。
61名無しさん@お腹いっぱい。:2000/11/02(木) 21:06
>54
6809版
ADDA #$90
DAA
ADCA #$40
DAA

6バイト
62名無しさん@お腹いっぱい。:2000/11/02(木) 22:47

#define BIT_Reverse(b@`c) ((c)=(c)^(1<<(b)))
63名無しさん@お腹いっぱい。:2000/11/03(金) 00:28
なんか、懐かしのテクニークスレッドと化してきたな(ワラ
64名無しさん@お腹いっぱい。:2000/11/03(金) 20:25
>>63
しょうがねぇじゃん。ここに書いてる奴はみんなレベル低いんだから。
65名無しさん@お腹いっぱい。:2000/11/03(金) 22:25
オマエモナーと言われたいM男君が増えてるな
逝ってやらん
66名無しさん@お腹いっぱい。:2000/11/05(日) 04:41
age
67名無しさん@お腹いっぱい。:2000/11/07(火) 06:49
ここにHerrさんいるでしょ。
68名無しさん@お腹いっぱい。:2000/11/07(火) 07:30
#DIV(x@` y) (y ? x / y : 0)

うーん、こんなのは?
望んだ結果が出ないかもしれんけど。
6968:2000/11/07(火) 07:44
あ、((y) ? (x) / (y) : 0) だな。
70名無しさん@お腹いっぱい。:2000/11/07(火) 12:47
>>68 何に使うの? 無限大を0に修正する? 用途を示してくんない?
71名無しさん@お腹いっぱい。:2000/11/07(火) 13:29
除算エラーにしたくないのでしょう。
72>70:2000/11/07(火) 13:31
たぶんゼロ除算例外を防止する為でしょう。

でも、その前の段階でyがゼロにならないよう管理すべきだと思ってたから
こんな事はやったことないな。逆に原因不明にするだけじゃん。
73名無しさん@お腹いっぱい。:2000/11/07(火) 13:56
>>72 わしもそう思う。

7470:2000/11/07(火) 14:33
ゼロ除算防止なのは、わかる。
オレも72の言うとおりこのマクロの使用では原因不明になるだけじゃないのか
と思う。

でもこういう形で記述すると上手く解決できる問題分野があり、それを
オレが知らないだけかとも思ったワケ。

そこらへん、どうよ >>68

#行列の特異値分解かなにかで 1/ε -> 0 (εは非常に小さい正数)と
置き換える場合とかがあった気がする。でもその場合はこのマクロは
使えないとも思う。
75名無しさん@お腹いっぱい。:2000/11/07(火) 15:04
ビット数をカウントするアルゴリズムでさぁ
0x7777とか、0x33333?とか使うやつあったっしょ
あれってどーゆーのだっけ?
76名無しさん@お腹いっぱい。:2000/11/07(火) 15:58
>>75
そこまで分かってるなら自分で検索すれ!
http://www.st.rim.or.jp/~phinloda/cqa/cqa15.html
7775:2000/11/07(火) 19:42
ありがと。(探したけど、見つからなかったの、ゆ・る・し・て)
78名無しさん@お腹いっぱい。:2000/11/07(火) 19:48
ちょっとズレるけどさ、マクロって関数コールのオーバーヘッドを
避けるために多用したりすることってないの?>制御分野のお方。
79>78:2000/11/07(火) 20:14
僕は制御じゃないけど
複雑になりそうな場合マクロをやめて関数にしてpragmaでinline化します。
移植性は下がるけど、可読性のほうが大事なので。
80名無しさん@お腹いっぱい。:2000/11/07(火) 21:28
制御用のクロスコンパイラは実装が貧困すぎて
inlineできないのがあります。
81名無しさん@お腹いっぱい。:2000/11/08(水) 02:49
最近は制御系にもgccとか使われる場合が結構ある。
82>78:2000/11/08(水) 05:12
あるよ。
コメントテク。
通常、
/*
....
*/
と書くが、
/*
....
//*/
と、コメントアウトしておくと、
//*
....
//*/
と、最初の一行に'/'一個追加するだけで、"...."の行が有効になる。

デバッグの時にちょっと便利。
84名無しさん@お腹いっぱい。:2000/11/08(水) 16:56
偶数化:変数 & -2
85名無しさん@お腹いっぱい。:2000/11/08(水) 17:44
>76
ちなみにどんなキーワードで見つけたの?すごい
86吾輩は名無しさんである:2000/11/08(水) 17:58
ここあとで修正しとく必要があるなーってとこには
/**/を書いときます。
87名無しさん@お腹いっぱい。:2000/11/08(水) 18:03
>>83
頼むからやめてくれ。
8868じゃないけど:2000/11/08(水) 19:04
>>68-74
もちろん、y=0にならないように書くのが正しいんだけど、仕事でゲームの
開発をしていると、最悪でも例外がおきないようにしておくのはわりと
大事だったりします。
# ハングるよりは変な場所に表示される方がマシってこと。
8968:2000/11/08(水) 19:23
あ、遅レスだけど 71-73@`88 の言う通りですね。
まあこれは 88 の言うように許容できる場合に限るので今考えると特殊な部類に入るかもね…
返す値を 0 じゃなくて自作関数で説明入りエラー吐くようにしておけば 0 割りのトラップもしやすいかもね。
90名無しさん@お腹いっぱい。:2000/11/09(木) 00:47
0が返っても許容できる、じゃなくて、
エラー処理の存在自体が許容できないわけです。ゲームでは。
91名無しさん@お腹いっぱい。:2000/11/09(木) 00:49
ちょっとしたテクニークスって事で
typedef で一度にポインタも定義出来ます

例:
typedef struct { なんとかかんとか} HOGE@`*PHOGE;
92名無しさん@お腹いっぱい。:2000/11/09(木) 01:04
<91
typedefの書式は、識別子の宣言とおなじだからね。
93名無しさん@お腹いっぱい。:2000/11/09(木) 01:08
常識と思うけど大文字化(ASCII 文字セット限定)
c には英文字が入ってると思いねぇ
char to_upper(char c) {
return c & ~0x20;
}
94名無しさん@お腹いっぱい。:2000/11/09(木) 01:46
>>91
const PHOGE
ってやってハマる奴がたまにいる。
95>>93:2000/11/09(木) 12:53
普通のtoupperじゃなんであかんの?
96Dr.URI:2000/11/10(金) 19:12
URIのことをかまってくださいー・・・

typedef struct{
  unsigned int Value : 2;
} ROTATE;

void FuncA()
{
  ROTATE st;
  unsigned int p;
  st.Value = 0;
  int i;
  for (i = 0; i < 10; i++)
  {
    p = st.Value++;
    printf("%d\n"@` p);
  }
}
97名無しさん@お腹いっぱい。:2000/11/10(金) 20:00
#define FLAG_CHECK( NUM@` FLAG) ((NUM & FLAG) / FLAG)
#define FLAG_ON( NUM@` FLAG) NUM |= (NUM ^ FLAG)
#define FLAG_OFF( NUM@` FLAG) NUM ^= (NUM & FLAG)

いまどきフラグなんてせこい使い方しないか?
98ビット操作を最近覚えた人:2000/11/10(金) 20:05
>>97
結構便利なんですが、、、
例えばゲームの毒、混乱、眠りなどの状態を表すとか。
99名無しさん@お腹いっぱい。:2000/11/10(金) 20:45
#define FLAG_CHECK(NUM@` FLAG) (!!(NUM & FLAG))
の方が好みだ。
100名無しさん@お腹いっぱい。:2000/11/10(金) 21:52
#define FLAG_CHECK(NUM@` FLAG) (((NUM)&(FLAG))==(FLAG))
101ビット?"猿"Zよか:2000/11/10(金) 23:30
ビットフィールド使うなぁ…
102名無しさん@お腹いっぱい。:2000/11/11(土) 04:45
>>101
俺もビットフィールド使うなぁ…
103:2000/11/12(日) 01:16
>>101-102
フラグとかをビットフィールトで、
struct {
int a:1;
int b:1;
} flag;
とかで定義した場合、すべてを0でクリアするとき、
*(int *)&flag=0;
とか書いてるんですけど、もっとエレガントな方法はないでしょうか?

i
104名無しさん@お腹いっぱい。:2000/11/12(日) 01:20
>>103
UNION使っとけ!
105名無しさん@お腹いっぱい。:2000/11/12(日) 01:59
この場合 int だと変な領域に書込んでしまわないか?
106名無しさん@お腹いっぱい。:2000/11/12(日) 02:22
左辺値のポインタのキャスト、よくある勘違いだよね。
107名無しさん@お腹いっぱい。:2000/11/12(日) 06:19
どなたか MMX の飽和演算を高速に真似る方法を教えてください。
4つの8ビットに加算したとき、ループせずに 0xff で飽和する演算を
考えていたのですが if 文を使う以外にいい方法が思いつきませんでした。

BYTE a@` b;
int c;
c = a + b;
if( c > (BYTE)0xff ) c = 0xff;
... 以下 4 つ繰り返し。
108名無しさん@お腹いっぱい。:2000/11/12(日) 06:56
0xff * 0xffサイズのテーブルを作る……
って、今のPCだと逆効果かも。
109108:2000/11/12(日) 06:57
あう、0x100 * 0x100サイズの間違い
ああ鬱だし脳
110名無しさん@お腹いっぱい。:2000/11/12(日) 07:14
int なんちゃら(unsigned char a@` unsigned char b)
{
  unsigned char retval;
  _asm {
    mov al@` a
    mov dl@` b

    add al@` dl
    sbb cl@` cl
    or al@` cl
    mov retval@` al
  }
  return retval;
}

うまく使わんと、パーシャルレジスタストールの餌食になるよ。
111110:2000/11/12(日) 07:18
clはdlでもよかった…
112>110:2000/11/12(日) 18:21
どこがテクニークなの?
113名無しさん:2000/11/12(日) 18:41
Cでやるならテーブルが一番手軽だろ。
BYTE Table[2]={0@`0xFF};
BYTE a@` b;
int c;
c = a + b;

c=c | Table[c >> 8];

255+255は512以下だからな。
114飽和加算:2000/11/12(日) 23:50
86系のアセンブラなら、alに3つ足して ahに127を足して、符号拡張
して、alとandかな。
4つ足した数を使って飽和させるほうが早い気がする。
どっちにしろ、cでifを使うのにくらべて、測定可能な速度差が出るかど
うかは、わからんけど。
115名無しさん@お腹いっぱい。:2000/11/13(月) 00:32
あまり気にしすぎるのも時間の無駄のような気がするなぁ。

前いた会社に最適化マニアがいて、きちんと動いてるのに
まだ速くする!とか言ってゴネてくれたが・・・。
116:2000/11/13(月) 03:47
>>104
unionだと、
union {
int all;
struct {
int a:1;
int b:1;
} bit;
} flag;
みたいな書き方になると思うのですが、それだと階層が一つ深くなる
じゃないですか。
>>105-106
すいません、どこがまずいのかわかんないです。
117名無しさん@お腹いっぱい。:2000/11/13(月) 04:05
>116
sizeof flag をかんがえてごらん
118107:2000/11/13(月) 05:22
>>108-115
皆さんご教授いただきありがとうございます
インラインアセンブラやビット操作で if 文は削ることが
できるんですね、勉強になりました。

>c=c | Table[c >> 8];

c |= (BYTE)((0x100) - (c >> 8));
これでもいいのかな
119>117:2000/11/13(月) 05:39
116のまずいのは、そっちじゃない気がするんだけど…
120119:2000/11/13(月) 05:43
116でなくて、>>103
121>113@`118:2000/11/13(月) 08:08
なんでOR演算になってるの?
122121:2000/11/13(月) 08:20
これでどう?
BYTE Table[2]={0xFF@`0};
c &= Table[c >> 8];
---
c &= (0 - (c >> 8));
123121@`122:2000/11/13(月) 08:25
あ、ごめん。大きな勘違いだった。氏のう。
124:2000/11/13(月) 11:52
すいません、まだ引っ張ります。
>>117 >>119
(flag.c)
int main(int argc@` char **argv) {
struct {
int a:1;
int b:1;
} flag;

*(int *)&flag=0;

printf("size of flag=%d\n"@` sizeof(flag));
printf("size of int=%d\n"@` sizeof(int));

return 0;
}
>./flag
size of flag=4
size of int=4
なんですけど…。ちなみにgccです。
125名無しさん@お腹いっぱい。:2000/11/13(月) 13:50
そりゃANSIだとビットフィールドはintに満たなくてもintに切り上げられるからねえ。
126107:2000/11/13(月) 14:37
>>121
>c &= (0 - (c >> 8));

ありがとうございます。飽和減算に使えそうです。

c |= -(c >> 8);
これで定数が消えました。いいかんじになってきました。
shr eax@` 8
neg eax
or ebx@` eax
(たぶんコンパイルするとこんな感じになりそう)
これ以上の高速化は 8bit * 4 を一気に処理するしかないでしょうか。
127名無しさん@お腹いっぱい。:2000/11/13(月) 17:08
テクニークとかく事。
128名無しさん@お腹いっぱい。:2000/11/13(月) 19:13
>>126
>c |= -(c >> 8);
>これで定数が消えました。いいかんじになってきました。

よくわからんな。その処理ってなんなんだ?
0か1になった奴を答えから引くことに何の意味がある?
129Visual名無しさん:2000/11/13(月) 21:03
>>128
0xffを越えてれば
c |= 0xff
でなけりゃ
c |= 0x00
って感じだから問題ないだろ。
130名無しさん@お腹いっぱい。:2000/11/13(月) 23:05
>128
8bit同士の加算だと、飽和してるのは 0x100〜0x1fe だ。
8bitシフトすると1 になるのだな。
で、これを符号反転すると(2の補数表現だと)0xff になって、
飽和しない場合は 0 を符号反転するから 0 。
で、>>129のようになってめでたしめでたし。
131123:2000/11/13(月) 23:54
>126
厳密には
c = (c | -(c >> 8)) & 0xFF;
だね。後で代入時にキャストするから書かなかっただけかな?
また勘違いだったらごめん。
132126:2000/11/14(火) 08:04
>>131
>後で代入時にキャストするから書かなかっただけかな?

はい。0xff でマスクかけたほうが ANSI 定義の
キャスト変換に合うのでいいのですが -1 になってるから
ま、いいかなと思いました。(^^;)
補数表現とかキャスト変換は自分の使っている処理系に依存しています。

まとめて処理するのを考えていますがなかなか難しいです。
133名無しさん@お腹いっぱい。:2000/11/14(火) 10:34
>132
4つ足してからなら>>114の方法でええんでないの?
Cで書くなら 0x7f00を足して16ビットシフトして符号反転、かな。
134133:2000/11/14(火) 10:35
15ビットシフトして、だった。
135133:2000/11/14(火) 10:39
ああ、0x7f00じゃだめだな、まぁ、察してくれや。
136某ランド:2000/11/14(火) 11:11
unsigned ClipAdd4(unsigned a@`int b)
{
unsigned c;
_asm {
 mov eax@`a;
 mov ebx@`b;
 and eax@`7f7f7f7fh;//MSB以外と
 and ebx@`7f7f7f7fh;//MSB以外と
 add eax@`ebx;
 mov ecx@`eax;
 mov eax@`a
 mov ebx@`b
 and eax@`80808080h;// ax@`bx@`cxのMSBが2つ以上1なら飽和
 and ebx@`80808080h;// ax@`bx@`cxのMSBがひとつでも1ならMSB=1
 add eax@`ebx
 mov ebx@`ecx
 rcr eax@`1
 shr ebx@`1
 and ebx@`40404040h
 add eax@`ebx
 mov ebx@`eax
 shl eax@`1
 shr ebx@`7    ;//各桁のキャリをLSBに合わせる
 and ebx@`01010101h
 add ebx@`7f7f7f7fh;//CF=0 then 7F else 80
 not ebx     ;//CF=0 then 80 else 7f
 and ebx@`7f7f7f7fh;//cf=0 then 00 else 7f
 and eax@`80808080h;
 or  ecx@`ebx
 or  eax@`ecx
 mov c@`eax; //帰値はeaxなので不要だが警告を黙らせる為に
 }
 return c;
}
137某ランド:2000/11/14(火) 11:28
がんばってみたけど、110さんの方法の方が短い
unsigned ClipAdd4(unsigned a@`int b)
{
unsigned c;
_asm {
 mov eax@`a;
 mov ebx@`b;
 add AL@`BL
 sbb CL@`CL
 or  CL@`AL
 ror ecx@`8
 shr eax@`8
 shr ebx@`8
 add AL@`BL
 sbb CL@`CL
 or  CL@`AL
 ror ecx@`8
 shr eax@`8
 shr ebx@`8
 add AL@`BL
 sbb CL@`CL
 or  CL@`AL
 ror ecx@`8
 shr eax@`8
 shr ebx@`8
 add AL@`BL
 sbb CL@`CL
 or  CL@`AL
 ror ecx@`8
 mov c@`ecx
 }
 return c;
}
138某ランド:2000/11/14(火) 11:32
ごめん、こっちだ
nsigned ClipAdd4(unsigned a@`int b)
{
unsigned c;
_asm {
 mov eax@`a;
 mov ebx@`b;
 add AL@`BL
 sbb CL@`CL
 add AH@`BH
 sbb CH@`CH
 or  CX@`AX
 ror ecx@`16
 shr eax@`16
 shr ebx@`16
 add AL@`BL
 sbb CL@`CL
 add AH@`BH
 sbb CH@`CH
 or  CX@`AX
 ror ecx@`16
 mov c@`ecx
 }
 return c;
}
139名無しさん@お腹いっぱい。:2000/11/14(火) 12:54
エナジーといったり
ヴァイタミンといったり
140>136:2000/11/14(火) 19:23
unsigned ClipAdd4(unsigned a@`unsigned b)
{
unsigned r = (a & 0x7f7f7f7f) + (b & 0x7f7f7f7f);
unsigned c = ((a>>1) & 0x40404040)
      + ((b>>1) & 0x40404040)
      + ((r>>1) & 0x40404040);
return  ( (~( ( (c>>7) & 0x01010101 ) + 0x7f7f7f7f) ) & 0x7f7f7f7f )
     | ( (c<<1) & 0x80808080 )
     |   r;
}
141126:2000/11/15(水) 00:45
>>133-140
126です。133さん、某ランドさん、140さん
ご教示いただき、ありがとうございます。

アセンブラとフラグ、強力ですね。
できればcで書こうかなと思っていたのですが、
アセンブラソース見ていたら
アセンブラのほうがいいのかもと思いました。(^^;)

皆さんのアセンブラコードのテクニーク、
有り難く拝読、教科書にさせていただきます。m(__)m

僕が使ってたコードはこんな感じです。

inline DWORD add4byte( DWORD a@` DWORD b)
{
DWORD t = (a & 0x7f7f7f7f) + (b & 0x7f7f7f7f);
DWORD u = (a ^ b) & 0x80808080;
DWORD m = ((a & b) | ((a ^ b) & t)) & 0x80808080;
m |= m - (m >> 7);
return (m ^ u) | t;
}

いまいち u@`m がマターリしてます。(^^;)
142sage
あ return (t ^ u) | m です。