1 :
名無しさん@お腹いっぱい。 :
2000/08/21(月) 15:53 if( hogehoge == 1 ) を if( 1 == hogehoge ) と書くと、イコールが一個しかなかったときエラーに なってくれる。 #罵倒をおそれずかきこめー
2 :
>1 :2000/08/21(月) 16:02
その話題ふると 恐い人がやってくるのでsageですぅ
(define (dbg x . s) (for-each display s) (display x) (newline) x)
つーか、1(最初の文章)に >#罵倒をおそれずかきこめー だけ書いて 2に内容書けばよかったのに・・・ struct hoge { char *ptr; char str[1]; }; C++だと使いにくいが…
VC++だと struct hoge{ char *ptr; char str[0]; } が出きるから、それに慣れてたせいでgccに移植するときに泣いたことが…
>4@`5 それって何に使うんですか?純粋に知りたいです。
つい、例にポインタをいれてしまったので、わかりにくいか。 例えば、文字列のリスト構造を実現する場合に リストを実現する構造体と、文字列を記憶する配列分の 2回、mallocを呼ぶ必要がある。 ところが、4の形式、つまり構造体の最後のメンバにchar[1]があると、 p = malloc(sizeof(struct hoge)+strlen(s)); strcpy(p->str@` s); という技が使える。 利点はmallocの呼び出し回数が減らせるため、 記憶領域的にも速度的にも有利になる。 もちろん、charに限らず、 「不定長の領域を本体とは別に確保する必要がある場合」に、 使う事が出来る。
誰も上げないので あげ
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)) ) ) の方が、多くの場合速度が速いコードが作れ、オーバーヘッドもほとんどない。 括弧が多いのは、今書いたからなんで、かんべん。
//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時代にはしょっちゅう使ったテクだが。
>15 つーか、それって3-i
17 :
名無しさん@お腹いっぱい。 :2000/08/22(火) 12:21
有名かもしれんが、 printf("%0*d\n"@` 4@` 123 );
18 :
6 :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 でいいと思うんだけど。なぜにスタックを使う? メモリを介さない分、速いだろうとおもうのですが。
23 :
20 :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; } こう言うのはやっぱり無駄な努力なんでしょうか。
どうだ、って、それもaを使って6回LDする方が速いんじゃねーの?
26 :
20 :2000/08/22(火) 21:08
>>25 かな?
まあ、アキュムレータを使わないでも済む方法、ってことで一つ……。
どっちが早いかは、今手元に資料が無いから分かんないよ。
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; すげーだろー。
>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で行うとほんの少し速くなるかも #こんなこと気にしながらプログラム書きたくないけど・・・
アタシはこっちの書き方のほうが好きよ。 for ( int i=N ; --i >= 0 ; ) {...} Nの表記が長いときに -1 が紛らわしくならないからよ。 0比較のため、というよりはインデックス逆巡回を書くときの イディオムよね。
35 :
名無しさん@お腹いっぱい。 :2000/10/31(火) 22:05
>>33 @`
>>34 境界判定のための比較が要らなくなるか、
って、アセンブラなら減産して0だった時点でZeroフラグ立つよね。
Cって、
オプティマイズされたオブジェクトなら、意外な方法で高速にしたりするんで、意味無し!
36 :
33 :2000/10/31(火) 22:10
>>34 >for ( int i=N ; --i >= 0 ; ) {...}
あ、、、きれい・・・いただきます:-)
>0比較のため、というよりはインデックス逆巡回を書くときの
>イディオムよね。
んーでも、比較すべき数値をレジスタにロードしなくて良い分
速いかなぁと・・・CPUによりけりですけど。
おまじないのように上記のようにがんばって書いてました。
「もうちょっと速くなりますように」とお祈りしながら・・・
37 :
33 :2000/10/31(火) 22:19
>>35 >Cって、
>オプティマイズされたオブジェクトなら、意外な方法で高速にしたりするんで、意味無し!
いや、先の例で、Nが変数のときには
for (int i=0; i < N; ++i) {...}
で、比較部分がほんのちょこっとだけ最適化あまくなるようなきがしません?
まあ、目に見えて速くなるわけではないですが、
藁にもすがりたいときにはおまじないとしてやってます。。。
だめっすかねぇ・・・
for ( int i=N ; --i >= 0 ; ) {...} って for ( int i=N ; i-- ; ) {...} でも可?
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の方が早くなるんですか? 最適化のあまりよろしく無いコンパイラ(あまり最適化に頼るのもなんなので) 普通程度の最適化がなされるコンパイラ(今時のコンパイラならそのぐらい基本的みたいな) の両方のケースで教えてください。
x=y=z=0; (;´Д`)
>>40 ループ回数違うような・・・
あと、iが0になったかどうかだけで判定してますが
Nが負で渡ってきちゃったときとか不安・・・
iのスコープも違ってるし・・・
スピードは同じっぽそう。逆アセンブルして確かめよう。
自分の目で確かめろ。 アゲてるやつはみんな白痴。
他人を白痴呼ばわりするのって楽しい?
int a@`b@`c; ....; if(int d=a-b) { d+=...; c+=d; } (;´Д`)
何これ?>47
>>45 たのしぃでぇ〜す。
酔っぱらい関数きぼん。
ここおもろい!!わしもかきこ!! nビットのマスク生成 (1 << n) - 1;
51 :
名無しさん@お腹いっぱい。 :2000/11/01(水) 23:09
あらら、sageばっかり・・・ あげちゃえ!
mvi a@`0 ではなく xra a とすると1バイトで済む メモリを0(等)で埋める歳にはpushを使うと速い dadで16bitの引き算をするには… bcとdeをxchgしたい時には… は当たり前の事か
bool light0; …; (light0?Enable:Disable)(LIGHTING); (;´Д`)
CMP AL@`0Ah SBB AL@`69h DAS 5バイトの1桁16進バイナリ−ASCII文字変換。 有名だねー。
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
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))))) ダサイ???
#define BIToff(b@`c) ((c) = (c) & ~(1 << (b))) c++ を無意識に使う怖さから、inline にしたほうがいいと思うが。
>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 しょうがねぇじゃん。ここに書いてる奴はみんなレベル低いんだから。
オマエモナーと言われたいM男君が増えてるな 逝ってやらん
66 :
名無しさん@お腹いっぱい。 :2000/11/05(日) 04:41
age
67 :
名無しさん@お腹いっぱい。 :2000/11/07(火) 06:49
ここにHerrさんいるでしょ。
#DIV(x@` y) (y ? x / y : 0) うーん、こんなのは? 望んだ結果が出ないかもしれんけど。
69 :
68 :2000/11/07(火) 07:44
あ、((y) ? (x) / (y) : 0) だな。
70 :
名無しさん@お腹いっぱい。 :2000/11/07(火) 12:47
>>68 何に使うの? 無限大を0に修正する? 用途を示してくんない?
除算エラーにしたくないのでしょう。
72 :
>70 :2000/11/07(火) 13:31
たぶんゼロ除算例外を防止する為でしょう。 でも、その前の段階でyがゼロにならないよう管理すべきだと思ってたから こんな事はやったことないな。逆に原因不明にするだけじゃん。
73 :
名無しさん@お腹いっぱい。 :2000/11/07(火) 13:56
74 :
70 :2000/11/07(火) 14:33
ゼロ除算防止なのは、わかる。
オレも72の言うとおりこのマクロの使用では原因不明になるだけじゃないのか
と思う。
でもこういう形で記述すると上手く解決できる問題分野があり、それを
オレが知らないだけかとも思ったワケ。
そこらへん、どうよ
>>68 #行列の特異値分解かなにかで 1/ε -> 0 (εは非常に小さい正数)と
置き換える場合とかがあった気がする。でもその場合はこのマクロは
使えないとも思う。
75 :
名無しさん@お腹いっぱい。 :2000/11/07(火) 15:04
ビット数をカウントするアルゴリズムでさぁ 0x7777とか、0x33333?とか使うやつあったっしょ あれってどーゆーのだっけ?
77 :
75 :2000/11/07(火) 19:42
ありがと。(探したけど、見つからなかったの、ゆ・る・し・て)
ちょっとズレるけどさ、マクロって関数コールのオーバーヘッドを 避けるために多用したりすることってないの?>制御分野のお方。
79 :
>78 :2000/11/07(火) 20:14
僕は制御じゃないけど 複雑になりそうな場合マクロをやめて関数にしてpragmaでinline化します。 移植性は下がるけど、可読性のほうが大事なので。
制御用のクロスコンパイラは実装が貧困すぎて inlineできないのがあります。
81 :
名無しさん@お腹いっぱい。 :2000/11/08(水) 02:49
最近は制御系にもgccとか使われる場合が結構ある。
82 :
>78 :2000/11/08(水) 05:12
あるよ。
コメントテク。 通常、 /* .... */ と書くが、 /* .... //*/ と、コメントアウトしておくと、 //* .... //*/ と、最初の一行に'/'一個追加するだけで、"...."の行が有効になる。 デバッグの時にちょっと便利。
偶数化:変数 & -2
85 :
名無しさん@お腹いっぱい。 :2000/11/08(水) 17:44
>76 ちなみにどんなキーワードで見つけたの?すごい
86 :
吾輩は名無しさんである :2000/11/08(水) 17:58
ここあとで修正しとく必要があるなーってとこには /**/を書いときます。
88 :
68じゃないけど :2000/11/08(水) 19:04
>>68 -74
もちろん、y=0にならないように書くのが正しいんだけど、仕事でゲームの
開発をしていると、最悪でも例外がおきないようにしておくのはわりと
大事だったりします。
# ハングるよりは変な場所に表示される方がマシってこと。
89 :
68 :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
ってやってハマる奴がたまにいる。
普通のtoupperじゃなんであかんの?
96 :
Dr.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)) の方が好みだ。
#define FLAG_CHECK(NUM@` FLAG) (((NUM)&(FLAG))==(FLAG))
ビットフィールド使うなぁ…
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
この場合 int だと変な領域に書込んでしまわないか?
左辺値のポインタのキャスト、よくある勘違いだよね。
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だと逆効果かも。
109 :
108 :2000/11/12(日) 06:57
あう、0x100 * 0x100サイズの間違い ああ鬱だし脳
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; } うまく使わんと、パーシャルレジスタストールの餌食になるよ。
clはdlでもよかった…
どこがテクニークなの?
Cでやるならテーブルが一番手軽だろ。 BYTE Table[2]={0@`0xFF}; BYTE a@` b; int c; c = a + b; c=c | Table[c >> 8]; 255+255は512以下だからな。
86系のアセンブラなら、alに3つ足して ahに127を足して、符号拡張 して、alとandかな。 4つ足した数を使って飽和させるほうが早い気がする。 どっちにしろ、cでifを使うのにくらべて、測定可能な速度差が出るかど うかは、わからんけど。
あまり気にしすぎるのも時間の無駄のような気がするなぁ。 前いた会社に最適化マニアがいて、きちんと動いてるのに まだ速くする!とか言ってゴネてくれたが・・・。
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 をかんがえてごらん
118 :
107 :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のまずいのは、そっちじゃない気がするんだけど…
120 :
119 :2000/11/13(月) 05:43
121 :
>113@`118 :2000/11/13(月) 08:08
なんでOR演算になってるの?
122 :
121 :2000/11/13(月) 08:20
これでどう? BYTE Table[2]={0xFF@`0}; c &= Table[c >> 8]; --- c &= (0 - (c >> 8));
123 :
121@`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に切り上げられるからねえ。
126 :
107 :2000/11/13(月) 14:37
>>121 >c &= (0 - (c >> 8));
ありがとうございます。飽和減算に使えそうです。
c |= -(c >> 8);
これで定数が消えました。いいかんじになってきました。
shr eax@` 8
neg eax
or ebx@` eax
(たぶんコンパイルするとこんな感じになりそう)
これ以上の高速化は 8bit * 4 を一気に処理するしかないでしょうか。
テクニークとかく事。
128 :
名無しさん@お腹いっぱい。 :2000/11/13(月) 19:13
>>126 >c |= -(c >> 8);
>これで定数が消えました。いいかんじになってきました。
よくわからんな。その処理ってなんなんだ?
0か1になった奴を答えから引くことに何の意味がある?
>>128 0xffを越えてれば
c |= 0xff
でなけりゃ
c |= 0x00
って感じだから問題ないだろ。
130 :
名無しさん@お腹いっぱい。 :2000/11/13(月) 23:05
>128
8bit同士の加算だと、飽和してるのは 0x100〜0x1fe だ。
8bitシフトすると1 になるのだな。
で、これを符号反転すると(2の補数表現だと)0xff になって、
飽和しない場合は 0 を符号反転するから 0 。
で、
>>129 のようになってめでたしめでたし。
131 :
123 :2000/11/13(月) 23:54
>126 厳密には c = (c | -(c >> 8)) & 0xFF; だね。後で代入時にキャストするから書かなかっただけかな? また勘違いだったらごめん。
132 :
126 :2000/11/14(火) 08:04
>>131 >後で代入時にキャストするから書かなかっただけかな?
はい。0xff でマスクかけたほうが ANSI 定義の
キャスト変換に合うのでいいのですが -1 になってるから
ま、いいかなと思いました。(^^;)
補数表現とかキャスト変換は自分の使っている処理系に依存しています。
まとめて処理するのを考えていますがなかなか難しいです。
133 :
名無しさん@お腹いっぱい。 :2000/11/14(火) 10:34
>132
4つ足してからなら
>>114 の方法でええんでないの?
Cで書くなら 0x7f00を足して16ビットシフトして符号反転、かな。
15ビットシフトして、だった。
ああ、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; }
エナジーといったり ヴァイタミンといったり
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;
}
141 :
126 :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 がマターリしてます。(^^;)
あ return (t ^ u) | m です。