【高速化】ビット演算 ..
348:デフォルトの名無しさん
07/06/20 14:21:11
要するに>>342は
01 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16
って意味
349:デフォルトの名無しさん
07/06/20 18:58:03
>>347-348が理解できない
350:デフォルトの名無しさん
07/06/20 19:07:00
ばっかー
351:デフォルトの名無しさん
07/06/20 19:09:51
2ビットのグレイコードは、2相エンコーダと呼ばれてる。 機械式のマウスなんかで使われている。
00 01 11 10 この順番で動けば 順方向 逆方向なら 00 10 11 01 と動くので区別出来る
2進数 00 01 10 11 でいいじゃないと思うだろうけど これだと一度に2ビット変化する箇所が2度出来る
センサーの取りつけに物凄い精度が要求される事になり安価なマウスに採用出来ない
352:デフォルトの名無しさん
07/06/21 00:53:52
ハミング距離でぐぐるといいよ
353:デフォルトの名無しさん
07/06/21 01:35:52
上位ビットから順に加算して途中でやめても、下位ビットの影響がそれより上に及ばない、っていう利点もある。
354:デフォルトの名無しさん
07/06/21 01:46:36
>>353
それ、具体的に教えて。
355:デフォルトの名無しさん
07/06/21 23:48:28
56の余りを求めるビットマスクはどのように書けばいいのでしょうか?
356:デフォルトの名無しさん
07/06/21 23:55:04
商か剰余を求めるビット演算を生成する CGI か何かを昔見かけたような気が・・・。
どこだっけかな・・・。
357:デフォルトの名無しさん
07/06/22 01:08:45
56の余りってなにさ?
358:デフォルトの名無しさん
07/06/22 01:17:06
x % 56でも計算したいんじゃね?
359:デフォルトの名無しさん
07/06/22 07:26:57
x % 56だと 2のベキ乗じゃないからビット演算1発では出来ないな
URLリンク(www.tensyo.com)
ここの後ろの方にビットマスクと繰り返し演算で剰余を求める方法がある
360:デフォルトの名無しさん
07/06/22 07:35:52
定数での除算って、こんなに繰り返し必要だったっけ?
3、4回の演算で書けたような気が・・・って、俺の記憶違いか?
361:デフォルトの名無しさん
07/06/22 07:37:37
それ、もしかしたら、2のべき乗での除算?
362:デフォルトの名無しさん
07/06/22 07:40:38
いや、それなら1回でいけるし。
あれ? 乗算だっけ?
363:デフォルトの名無しさん
07/06/22 07:42:31
ああ、何か乗算だった気もしてきた。スマン。
364:デフォルトの名無しさん
07/06/22 07:50:41
2^N>=b となるNを求める(2^N == 1<<N) ・・・・・ N=6 2^N=64
B=2^N-b ・・・・・・ 64 -56 = 8
C=2^N-1 ・・・・・・ 64 - 1 = 63
while(a>=2*b){ B *(a>>N) + a&C };
while(a >=56*2 ){ 8 *(a>>6) + a&63 };
while(a >=56*2 ){ ( (a>>6) <<3 ) + a&63 };
1ループで3ビット改善するから 32bitなら 最大10回ちょっとのループか
365:デフォルトの名無しさん
07/06/22 08:00:17
56*73 =4088 で 2^12-8 だから
a = ( (a>>12)<<3 ) + a & 4095; を 前段でやれば改善するんじゃないかな
366:デフォルトの名無しさん
07/06/22 09:49:41
最近のコンパイラは定数の割り算は掛け算に置き換えるね。
56で割るロジックをコンパイルしたら、-1840700269を掛けた後に
ビットシフトと足し算をしていた。それ以上追っかけるのはパス。
367:デフォルトの名無しさん
07/06/22 09:51:15
インテルのコンパイラで a=a%56 の出力はこんな感じ(aはunsigned int)。
LARGE_INTEGER li;
li.QuadPart = UInt32x32To64(a>>3,0x24924925);
int d = li.HighPart;
a -= ((d<<3)-d)<<3;
aがsigned intの場合は、もう少し複雑。
368:デフォルトの名無しさん
07/06/22 10:11:46
なるほど、>366の数値が0x92492493だからシフト量が違う同じビットパターンなのか。
369:デフォルトの名無しさん
07/06/22 10:17:29
でもまあPCのCPUみたいに掛算が高速だったらって前提だな。
1チップとかだと 掛算はビットサイズに応じたサイクル数かかるし
掛け算持ってないCPUもあるし
370:デフォルトの名無しさん
07/06/22 10:21:39
大丈夫、そういうCPUは割り算も遅い。
371:デフォルトの名無しさん
07/06/22 10:26:29
a = ( (a>>18)<<3 ) + a & ((1<<18)-1);
a = ( (a>>12)<<3 ) + a & 4095;
a = ( (a>>9)<<3 ) + a & 511
a = ( (a>>6) <<3 ) + a & 63;
a = ( (a>>6) <<3 ) + a & 63;
while(a>=56) a-=56;
これならどうだろ?
372:デフォルトの名無しさん
07/06/22 10:34:31
演算子の数が20を超えてるな。
素直にdiv使った方が速いかもしれない。
373:デフォルトの名無しさん
07/06/22 10:45:50
もうちょっとバランスをうまく取れば、1行減らせるかもな
374:デフォルトの名無しさん
07/06/22 11:08:06
結局 3bit 単位だからなあ
最初は
a = ( (a>>15)&(-7) ) + a & ((1<<18)-1);
か
a = ( (a>>12)&(-7)) + a & ((1<<15)-1);
のどっちかで、どっちも32->18.4bit
次は
a = ( (a>>6)&(-7) ) + a & 511 でも12.5bit
a = ( (a>>9)&(-7) ) + a & 4095; でも12.5bit
あとは3ビットづつしか落とせない。 無理
375:デフォルトの名無しさん
07/06/22 11:17:53
あ、
a = ( (a>>18)<<3 ) + a & ((1<<18)-1);
a = ( (a>>12)<<3 ) + a & 4095;
a = ( (a>>6) <<3 ) + a & 63;
a = ( (a>>6) <<3 ) + a & 63;
while(a>=56) a-=56;
とやれば、最後の while はせいぜい3回のループでいいか
376:デフォルトの名無しさん
07/06/22 11:26:49
>>372
div 命令は、持っていてもbit数のサイクルかかるのが殆どだよ。 だから >>366-367 のような最適化がされるんだし
377:デフォルトの名無しさん
07/06/22 11:33:21
ただ PC の場合はレイテンシがかかるだけだから、divを使った方が速いかもしれないな。
378:デフォルトの名無しさん
07/06/22 11:37:09
>>367
ここまでしても idiv より速いのか・・・。
379:デフォルトの名無しさん
07/06/22 11:48:18
Pentium II およびPentium III プロセッサの実行ユニット
整数乗算は レイテンシ4、スループット1/ サイクル
除算は浮動小数点ユニットで行われ
FDIV 命令 レイテンシ: 単精度17 サイクル、倍精度36 サイクル、拡張精度56 サイクル
だから、桁違いにレイテンシが大きい。
380:デフォルトの名無しさん
07/06/22 11:50:39
浮動小数点ユニットで行われるのか?!
381:デフォルトの名無しさん
07/06/22 11:58:11
だって 整数乗算ユニットってのはブロック図にあるが、 整数除算ユニットってのはどこにも無いだろ?
除算ってのはコストのわりに利用頻度が少ないから、どうせ浮動小数点ユニットもってるからそっちで計算させてるのさ
仮に、整数演算ユニットで除算をしたとしても、結局32サイクルはかかるし、その間加減算比較ユニットの一つが潰れてしまうからな
382:デフォルトの名無しさん
07/06/22 12:14:11
そうだったのか・・・。
そら遅いわな。
383:デフォルトの名無しさん
07/06/22 12:27:02
>>381
これ以上はスレ違いになるがつっこませてくれ。
浮動小数点ユニットがIEEE754(だったっけ)で処理する場合、単精度で23ビット、倍精度で52ビットの精度だろ。
被序数が32ビット整数ならともかく、64ビット整数の除算は精度の問題上アウトだぞ。
384:デフォルトの名無しさん
07/06/22 12:34:23
>>383
Intel 系の浮動小数点ユニットは
拡張倍精度(80ビット/仮数部64ビット)で行われてるから大丈夫。
385:デフォルトの名無しさん
07/06/22 12:44:20
>>384
まじか!と思って何年も開いていない重たいバインダーを紐解いてみたら、たしかにそう書かれているな。
しかも本当は63ビット精度なのに、ケチりビットをケチらない荒技で対処してるし・・・。
そのうえx87コプロに限ればつねに拡張倍精度で計算されることになってたりして、もうね、馬(ry。
386:デフォルトの名無しさん
07/06/22 13:02:46
56 = 7*2^3 だから
x % 56 = (x % 7)<<3 + (x & 7)
x/7 を round(2^32/7 )>>32 で近似したのが >>367
387:デフォルトの名無しさん
07/06/22 13:07:24
しかし、1/7って面白いなぁ。10進だけでなく16進でも綺麗な循環小数になるんだな。
388:デフォルトの名無しさん
07/06/22 13:08:10
もしかして >>375 のような事しても idiv 使うより速いって事はありえるのか?
389:デフォルトの名無しさん
07/06/22 16:51:54
>>388
実際に速度を比較してみれば?
Cの場合、&より+の方が優先順位が高いので、
>>375の&演算には括弧が必要だね。
390:デフォルトの名無しさん
07/06/22 17:06:59
そうだね。
391:デフォルトの名無しさん
07/06/22 18:03:24
やってみた。
function getRDTSC: int64;
asm DW $310F //RDTSC
end;
var ww:Integer;
procedure TForm1.Button1Click(Sender: TObject);
const CNT=100000;
var t1,t2,t3:int64;
i,a:Integer;
begin
t1:=getRDTSC;
for i := 1 to CNT do begin
a := i;
a := ((a shr 15) and 7) + (a and ((1 shl 18) - 1));
a := ((a shr 9) and 7) + (a and 4095);
a := ((a shr 3) and 7) + (a and 63);
a := ((a shr 3) and 7) + (a and 63);
while a >= 56 do a := a - 56;
ww:=a; {mod と同じになるように}
end;
t2:=getRDTSC;
for i := 1 to CNT do ww:=i mod 56;{ローカル変数に代入すると最適化で消えるので}
t3:=getRDTSC;
Memo1.Lines.Add(format('T2-T1 %10d',[t2-t1]));
Memo1.Lines.Add(format('T3-T2 %10d',[t3-t2]));
end;
---------------
T2-T1 1610740
T3-T2 4317497
間違いでなければ mod 命令より速い
392:デフォルトの名無しさん
07/06/22 18:06:18
そうだね。
393:デフォルトの名無しさん
07/06/22 18:09:15
上の and 7 は and -8 の間違いだった
394:デフォルトの名無しさん
07/06/22 18:33:37
でも、掛算を使うのはさらに半分だった。
for i := 1 to CNT do
begin
a := i shr 3;
asm
mov eax,$24924925;
IMUL a;
mov a,EDX;
end;
ww := i - ((a * 7) shl 3);
// if ww<> (i mod 56) then Memo1.Lines.Add( 'Err');
end;
t4 := getRDTSC;
T2-T1 169613675
T3-T2 436034967
T4-T3 86040347
395:デフォルトの名無しさん
07/06/22 18:40:43
結局 idiv : ビット演算 : 掛算の 重さは およそ 5 : 2 : 1 だった。
ビット演算 思ったよりガンバレるな。
396:デフォルトの名無しさん
07/06/22 19:24:47
これを高級言語で書いたら他の人に白い目で見られるだけならまだいいんだけど
ひどい場合は書き直しすら命じられまする(´・ω・`)
397:デフォルトの名無しさん
07/06/22 19:44:35
そうだね。
398:デフォルトの名無しさん
07/06/22 20:36:07
>>396
高級言語の目的の一つが可読性の向上だからね。
コメントで解説いれても却下される場合すらあると思うよ。
399:デフォルトの名無しさん
07/06/22 20:48:20
除算命令がないCPUなら有効だろうけど
x % 60 が欲しい時とか、いちいち変換が大変だよな
400:デフォルトの名無しさん
07/06/22 21:47:03
導出は機械的なプロセスだから、スクリプトみたいなのでサクッと求めるといいと思う。
可能なら、最適化の一環としてコンパイラに組み込むのがベストだが。
401:デフォルトの名無しさん
07/06/22 23:23:02
だから、掛け算化はgccでもやってるって。
402:デフォルトの名無しさん
07/06/23 00:18:01
>>401
ほんとにやってる?やらない場合も多いけど
絶対さぼってる
403:デフォルトの名無しさん
07/06/23 01:26:20
昔のx86みたいにALUしかないCPUはそういう風にやってたのかぁ、勉強になりました。
404:デフォルトの名無しさん
07/06/23 01:29:46
>>403
定数割り算の掛け算化が行われない例があれば、逆に教えて欲しい。
まさか、最適化オプションを指定しないとしてくれないなんて言わないよね。
405:デフォルトの名無しさん
07/06/23 01:31:50
>>404
深く考えず単純に引き算かと
今考えると空恐ろしいやり方だw
406:デフォルトの名無しさん
07/06/25 10:58:28
>404は>402宛てなんだろうなぁ。それはいいけど、>405は何を言いたいのだろう……
407:デフォルトの名無しさん
07/06/25 19:13:34
きっと8086には除算命令が無いと思ってるんだろう。
408:デフォルトの名無しさん
07/06/25 19:57:27
Pen3では除算を浮動小数点ユニットでされるというのを見て、
浮動小数点ユニットが無い時には除算も無かったと思ったのかな
除算そのものはシフト減算比較の繰り返しで出来るから
サイクル数さえ必要なだけかければマイクロプログラム方式ならそうコストかからない
掛け算と変わらない。
409:405
07/06/26 07:50:34
>>406
あ、ほんとだね
>>407,408
んにゃ、引き算の連続で商余求めてたのかなと
410:デフォルトの名無しさん
07/06/26 08:23:37
これは固定での剰余だから高速化出来るのであって
変数での剰余になると、結局コードで書いても加え戻し法(復元法)とかになるので
除算命令使った方がやっぱり速い。
411:デフォルトの名無しさん
07/06/28 00:42:51
DSP(やCell)では逆数をニュートン法で求めるのが定番
412:デフォルトの名無しさん
07/07/08 16:40:57
8086で除算命令使うとCPUの方で乗算とシフト命令に解釈しなおす訳?
ということは除算命令自体はマクロになるのかな
413:デフォルトの名無しさん
07/07/08 18:16:20
は?
414:デフォルトの名無しさん
07/07/08 19:57:33
除算命令に出くわして、せっせとメモリ中のコードを書き換える、けなげな86の姿を想像した・・・
415:デフォルトの名無しさん
07/07/11 22:50:58
言う事聞かない奴隷なんかいらない
416:デフォルトの名無しさん
07/07/21 07:45:05
>>412
マイクロプログラムで処理してるんだろ
>8086のマイクロコードは、命令長が21ビットで、プログラムサイズは504ステップであった
417:デフォルトの名無しさん
07/07/21 10:07:54
そろそろダンゴさんに〆てもらうか。
418:デフォルトの名無しさん
07/07/21 21:50:22
うむ
419:デフォルトの名無しさん
07/08/03 07:04:32
あ
420:デフォルトの名無しさん
07/08/03 11:40:01
ダゴンを深淵から呼びだしては駄目だ
421:だんごの輪島
07/08/03 12:15:43
ん?
422:デフォルトの名無しさん
07/08/03 21:06:03
は?
423:デフォルトの名無しさん
07/08/12 09:53:59
は
424:デフォルトの名無しさん
07/08/12 10:01:53
ビッチ演算
425:デフォルトの名無しさん
07/08/12 14:27:31
ビット大佐
426:デフォルトの名無しさん
07/08/14 10:07:39
age
427:デフォルトの名無しさん
07/08/14 11:48:05
あ
428:デフォルトの名無しさん
07/08/16 20:39:50
〆
429:デフォルトの名無しさん
07/08/18 23:05:50
あgw
430:デフォルトの名無しさん
07/08/18 23:09:42
ぬるぽ
431:デフォルトの名無しさん
07/08/20 01:29:30
ちょっとスレの趣旨と違うと思うんだけど、適当なところが無かったので、
アドバイス頼む。
アドレスのアライメントをチェックするためにポインタをintにキャストして
&でビットテストしてる。
extern char *p;
if(((int)p & 3) == 0){
//32bit境界にある処理…
}
だけどアドレスをintにキャストするのは64bit時代的に行儀悪いみたい。
でもアドレスをビットテストしたいという状況は普通にあると思うんで、
こういう場合C系的にはどう書くのが上手な作法なの?
432:デフォルトの名無しさん
07/08/20 01:38:30
>>431
Linux界隈じゃ unsigned long へのキャストが一般的とされてるが
個人的には嫌い
433:デフォルトの名無しさん
07/08/20 01:40:50
intptr_t / uintptr_t を使えばいいんじゃない?
434:デフォルトの名無しさん
07/08/20 08:48:31
下位ビットだけ入ればいいので、charでもいい
435:デフォルトの名無しさん
07/08/20 23:58:10
さすがにそれはありえないだろ?
436:デフォルトの名無しさん
07/08/21 00:11:51
なぜそう思うの?
437:デフォルトの名無しさん
07/08/21 00:33:14
バイトオーダー
438:デフォルトの名無しさん
07/08/21 00:37:00
バイトオーダーは関係ないかと
439:・∀・)っ-○◎●
07/08/21 00:52:14
WindowsならUINT_PTRにキャスト
440:デフォルトの名無しさん
07/08/21 01:00:01
ダンゴさんがピシっと〆めたな。
441:・∀・)っ-○◎●
07/08/21 01:19:06
うんこうんこうんk
442:デフォルトの名無しさん
07/09/09 23:01:40
う
443:デフォルトの名無しさん
07/09/09 23:35:23
ん
444:デフォルトの名無しさん
07/09/09 23:37:25
ち
445:デフォルトの名無しさん
07/09/09 23:45:20
ゃ
446:デフォルトの名無しさん
07/09/16 06:34:05
あ
447:デフォルトの名無しさん
07/09/19 12:28:31
は
448:デフォルトの名無しさん
07/09/19 12:32:11
た
449:デフォルトの名無しさん
07/09/19 13:50:16
ぼ
450:デフォルトの名無しさん
07/09/19 23:03:56
ぬ
451:デフォルトの名無しさん
07/09/19 23:56:29
る
452:デフォルトの名無しさん
07/09/20 00:04:43
ぽ
453:デフォルトの名無しさん
07/09/20 18:42:49
>>450-452
ガ
454:デフォルトの名無しさん
07/09/22 00:43:27
スレリンク(tech板:555番)
これもっと簡単にならないかな?
455:デフォルトの名無しさん
07/09/22 07:06:58
>>454
--------------------
int my_fputwc(wint_t c, FILE *fp)
{ wint_t r = fputwc(c, fp);
return (r == WEOF) ? EOF : r;
}
int wtbl[0x10000];
void dokkade_jikkou(void ) {
int i;
for (i = 0; i < 0x10000; i++)
wtbl[i] = i;
wtbl[0xffff] = EOF;
}
int my_fputwc(wint_t c, FILE *fp) return wtbl[fputwc(c, fp);]; }
みたいなこと(WEOF(wint_tの0xffff)をEOF(intの-1)に変換)
をもっとスマートに行う方法ないですかね。
---------これで何の不満があるんだ?-----------
wtbl[0xffff] = EOF;
for (i = 0; i < 0xffff; i++)
wtbl[i] = i;
}
--------------------
456:デフォルトの名無しさん
07/09/27 20:24:00
age
457:デフォルトの名無しさん
07/09/29 23:03:31
int rotate_0_9(int a){a++;return(a+(((a+6)>>4)+(((a+6)>>4)<<1))<<1)&15;}
or
int rotate_0_9(int a){a++;return(a+((a+6)>>4)*6)&15;}
引数が0〜8の時1を加算し、引数が9の時0を返す。
458:デフォルトの名無しさん
07/09/29 23:17:24
return ++a%9;
459:デフォルトの名無しさん
07/09/29 23:39:43
% はビット演算じゃないだろう
460:デフォルトの名無しさん
07/09/29 23:58:36
int rotate_0_9(int a){return a<9?a+1:0;}
461:デフォルトの名無しさん
07/09/30 00:06:34
DAA
462:デフォルトの名無しさん
07/09/30 00:15:35
>>457
>>458
>>460
どれが速い?
463:デフォルトの名無しさん
07/09/30 00:20:18
実測あるのみ
464:デフォルトの名無しさん
07/09/30 00:34:05
試してみた!
cl /O2 rot9.c
rot9
rotate_0_9_457_1 1873 msec
rotate_0_9_457_2 1272 msec
rotate_0_9_458 4016 msec
rotate_0_9_460 641 msec
>>460が圧倒的だった(俺もそう思ってた)
ソースに続く
465:デフォルトの名無しさん
07/09/30 00:34:50
>>464のソース (VC6SP4)
----------------------------
#include <windows.h>
#include <stdio.h>
int rotate_0_9_457_1(int a){a++;return(a+(((a+6)>>4)+(((a+6)>>4)<<1))<<1)&15;}
int rotate_0_9_457_2(int a){a++;return(a+((a+6)>>4)*6)&15;}
int rotate_0_9_458(int a){return ++a%9;}
int rotate_0_9_460(int a){return a<9?a+1:0;}
//#define COUNT_TIMES 0x7fffffff
#define COUNT_TIMES 0x7ffffff
#define TEST(func) \
dwTime = GetTickCount(); \
for(i = 0, count = 0; count < COUNT_TIMES ; count++) { \
i=func(i); \
} \
printf( # func " %d msec\n", GetTickCount() - dwTime);
main() {
int i, count;
DWORD dwTime;
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
Sleep(100);
TEST(rotate_0_9_457_1)
Sleep(100);
TEST(rotate_0_9_457_2)
Sleep(100);
TEST(rotate_0_9_458)
Sleep(100);
TEST(rotate_0_9_460)
return 0;
}
----------------------------
466:デフォルトの名無しさん
07/09/30 00:38:34
printf( # func " %d msec (i:%d)\n", GetTickCount() - dwTime, i);
と変更して計算結果も表示してみたら>>457の最初の式の結果がおかしい事に
気付いたんだけど。
rotate_0_9_457_1 1862 msec (i:0)
rotate_0_9_457_2 1272 msec (i:7)
rotate_0_9_458 3986 msec (i:7)
rotate_0_9_460 671 msec (i:7)
467:デフォルトの名無しさん
07/09/30 00:40:00
int rotate_0_9_467(int a){
static int t[10]={1,2,3,4,5,6,7,8,9,0};
return t[a];
}
表引き。
これもやってみてくれ。
468:デフォルトの名無しさん
07/09/30 00:49:01
>>457
やってみるよ。
457_1のiの推移
0 2 6 14 4 10 12 0 2 6 14 4 10 12 0 2 6 14 4 10 12 0 2 6 14
無茶苦茶だった。
469:デフォルトの名無しさん
07/09/30 00:55:09
rotate_0_9_457_1 1893 msec (i:0)
rotate_0_9_457_2 1272 msec (i:7)
rotate_0_9_458 3996 msec (i:7)
rotate_0_9_460 661 msec (i:7)
rotate_0_9_467 621 msec (i:7)
テーブル引きのがわずかに速いね。
>>460と>>467が微差だったんでカウンタ倍にしてみた。
#define COUNT_TIMES 0xfffffffに変更。
rotate_0_9_457_1 3535 msec (i:2)
rotate_0_9_457_2 2553 msec (i:5)
rotate_0_9_458 7991 msec (i:5)
rotate_0_9_460 1332 msec (i:5)
rotate_0_9_467 1202 msec (i:5)
計ったPCはThinkPad X31 (PenM1.6G Banias) XPSP2
470:デフォルトの名無しさん
07/09/30 00:57:00
あと>>458は0〜8の繰り返しで条件が違うんで
int rotate_0_9_458(int a){return ++a%10;}
に修正してる
471:デフォルトの名無しさん
07/09/30 01:13:29
_rotate_0_9_457_2 PROC NEAR
; 13 : int rotate_0_9_457_2(int a){a++;return(a+((a+6)>>4)*6)&15;}
mov ecx, DWORD PTR _a$[esp-4]
inc ecx
lea eax, DWORD PTR [ecx+6]
sar eax, 4
lea eax, DWORD PTR [eax+eax*2]
lea eax, DWORD PTR [ecx+eax*2]
and eax, 15
ret 0
_rotate_0_9_457_2 ENDP
掛け算消えるんだね
_rotate_0_9_458 PROC NEAR
; 14 : int rotate_0_9_458(int a){return ++a%10;}
mov eax, DWORD PTR _a$[esp-4]
mov ecx, 10
inc eax
cdq
idiv ecx
mov eax, edx
ret 0
_rotate_0_9_458 ENDP
見るからに遅そうな
472:デフォルトの名無しさん
07/09/30 01:16:44
_rotate_0_9_460 PROC NEAR
; 15 : int rotate_0_9_460(int a){return a<9?a+1:0;}
mov eax, DWORD PTR _a$[esp-4]
cmp eax, 9
jge SHORT $L53312
inc eax
ret 0
$L53312:
xor eax, eax
ret 0
_rotate_0_9_460 ENDP
普通だね
_rotate_0_9_467 PROC NEAR ; COMDAT
mov eax, DWORD PTR _a$[esp-4]
mov eax, DWORD PTR _?t@?1??rotate_0_9_467@@9@9[eax*4]
ret 0
_rotate_0_9_467 ENDP
短いね
この短さがテーブル参照のオーバーヘッドを相殺してる?
けどaが10以上だったら脂肪
473:デフォルトの名無しさん
07/09/30 01:27:47
まあ表引きはキャッシュから外れた時にペナルティがあるから
平均的には>460がいいんだろうな。
474:デフォルトの名無しさん
07/09/30 02:05:05
>>473
確かに、別の環境だと逆転してたり。
#Celeron 430@2.4G XPSP2
rotate_0_9_457_1 1750 msec (i:2)
rotate_0_9_457_2 1359 msec (i:5)
rotate_0_9_458 2969 msec (i:5)
rotate_0_9_460 719 msec (i:5)
rotate_0_9_467 860 msec (i:5)
#Core2Duo 4300@3.2G XPSP2
rotate_0_9_457_1 1281 msec (i:2)
rotate_0_9_457_2 1000 msec (i:5)
rotate_0_9_458 2172 msec (i:5)
rotate_0_9_460 516 msec (i:5)
rotate_0_9_467 656 msec (i:5)
475:デフォルトの名無しさん
07/09/30 04:40:29
%は割り算があるから遅いってことか。0〜9ではなく0〜2^n-1の場合にかぎり使えばいいかな。
でも実際の仕事では0〜99のローテートでも%で書いたりするなあ。
476:デフォルトの名無しさん
07/09/30 08:29:40
剰余は定数除算よりも更に遅い。
477:デフォルトの名無しさん
07/09/30 09:14:40
その剰余をビット演算でなんとか...
478:デフォルトの名無しさん
07/09/30 10:11:46
このスレの355から、剰余をビット演算でする方法が書かれているよ。
入力が必ず0〜9なら
a=((a+7)&15)-6; // 0〜8 が 1〜9 9が-6
(aの符号拡張か 4bitの算術右シフト結果)のビット反転と and
479:457
07/09/30 23:43:50
ふぬぅ、やっぱ分岐しない上にテーブルも使わない奴は遅いな。
480:デフォルトの名無しさん
07/09/30 23:45:02
逆に考えて、分岐する上にテーブルも使う奴は・・・
すまん、逆に遅くなりそうだ。
481:デフォルトの名無しさん
07/10/01 16:44:48
modも内部的には分岐してるだろ。RISCならよくわかる。
482:デフォルトの名無しさん
07/10/01 17:41:59
え〜(*o*) それは2のn乗の場合とそうでないので分けてるとか?
483:ヽ・´∀`・,,)っ━━━━━━┓
07/10/04 02:56:19
剰余 = 披除数 − (除数 * 商)
一般的には商と剰余は同時に求めることが可能
484:デフォルトの名無しさん
07/10/21 17:07:33
age
485:デフォルトの名無しさん
07/10/21 18:36:55
剰余のビット演算への変換ならこのページにあるよ。
URLリンク(www.tensyo.com)
縛りを入れるともっと高速化出来そう…
486:デフォルトの名無しさん
07/10/23 00:23:05
ある変数の値が
2018か2019
4049か4050
であるか判別する方法は4回比較するしか
ないかな?
487:デフォルトの名無しさん
07/10/23 00:49:07
愚直な方法だけど比較2回には減らしてみた。
bool check(int value) {
const int mask = ~1;
if( (value & mask) == 2018 || ((value + 1) & mask) == 4050 ) return true;
return false;
}
488:デフォルトの名無しさん
07/10/23 01:56:04
テストしてないけど。
bool check(int value) {
const int mask = ~1;
if (((abs(value - 3034) + 1) & mask) == 1016) return true;
return false;
}
489:デフォルトの名無しさん
07/10/23 09:11:06
AND も加算も比較=減算も、演算量は同じ、ってこと考えたら、どっちも減ってない。
比較4回に比べてリーダビリティは下がってる。
490:デフォルトの名無しさん
07/10/23 09:53:31
switch (value) {
case 2018: case 2019: case 4049: case 4050:
doit();
}
491:デフォルトの名無しさん
07/10/23 11:06:26
if (v == 2018 || v == 2019 || v == 4049 || v == 4050) return 1;
return 0;
0m48.123s
0m2.250s
const int mask = ~1;
if ((v & mask) == 2018 || ((v + 1) & mask) == 4050) return 1;
return 0;
0m53.281s
0m2.278s
const int mask = ~1;
if (((abs (v - 3034) + 1) & mask) == 1016) return 1;
return 0;
0m52.661s
0m2.167s
switch (v) {
case 2018: case 2019: case 4049: case 4050:
return 1;
}
return 0;
0m46.065s
0m2.087s
if (v < 2018 || (v > 2019 && (unsigned int) (v - 4049) > 1)) return 0;
return 1;
0m45.938s
0m2.086s
いろいろ測ってみた
コンパイラやマシンによって違うと思うけど
492:デフォルトの名無しさん
07/10/23 11:25:06
4回比較より下の2つのが短いのが不思議ですね。
入力が多数回で、4つの値が均等にバラつくという条件にしたら、最後まで演算しない4回比較
がイイかと思えますが。
493:デフォルトの名無しさん
07/10/23 11:26:33
>>489
可読性も考慮するの?このスレで?
494:デフォルトの名無しさん
07/10/23 11:29:15
ちなみに最後の一個はswitchバージョンのアセンブル出力をCに直したもの
495:デフォルトの名無しさん
07/10/23 12:45:37
iccで試してみた。
# icc -xP -O3 -ip
# icc 10.0
上から、0.3, 0.23, 0.33, 0.3, 0.22[sec/(10000 * 10000call)]だった。
どうやらswitchで書いても一番上と同じような出力になるようだ。
gccでも試してみた。
# gcc -O3 -funroll-loops
# gcc 3.4.6
こちらは、0.16, 0.22, 0.27, 0.17, 0.22[sec/(10000 * 10000call)]だった。
なんでこんなに速いんだ?w
496:デフォルトの名無しさん
07/10/23 21:35:27
>>495
アセンブリコードで比較してみると分かるんじゃね?
497:デフォルトの名無しさん
07/10/23 23:12:05
俺には>>486が
if(v==2018||v==2019){
}else if(v==4049||v==4050){
}else{
}
って条件に読めるんだが
498:デフォルトの名無しさん
07/10/23 23:17:57
俺も俺も
499:デフォルトの名無しさん
07/10/24 00:23:34
>>486
日本語でおk
やっと言う側に回れたか
500:デフォルトの名無しさん
07/10/24 01:05:28
>>497
いや、今日きちんとみかか村に出撃して
糞仕様について問い詰めてきたけど
case 2018: case 2019: case 4049: case 4050:
で正しい
どうもみんなありがとう
501:デフォルトの名無しさん
07/11/02 19:56:43
>491
>if (((abs (v - 3034) + 1) & mask) == 1016) return 1;
ここら辺の数値の導き方教えてください
どいった関係で3034とか出すの?ど素人ですんません
502:デフォルトの名無しさん
07/11/02 20:15:08
>>501
2018+4050=2019+4049=3034+3034
v = [2018 or 2019 or 4049 or 4050] の時
abs(v - 3034) = [1015 or 1016]
abs (v - 3034) + 1 = [1016 or 1017]
mask=0xfffffffeより奇数はそれを超えない偶数に変換される。
(abs (v - 3034) + 1) & mask = 1016
503:デフォルトの名無しさん
07/11/02 21:44:43
>502
ものっそい感動しました
久しぶりに成長した気がする
この括り方すげー
504:デフォルトの名無しさん
07/11/03 20:48:03
もはや逆方向にソースから動作仕様を求めることはほぼ不可能だな
505:デフォルトの名無しさん
07/11/04 06:35:34
かっこいい BIN→BCD は?
506:デフォルトの名無しさん
07/11/04 08:47:47
速さなら、00h,01h,02h・・・を表に持ち、binで表引き。 <99のチェックは必要。
サイズなら、((bin/16)<<4) | (bin%16) ・・・バイト版。 <99のチェックは必要。
ワードは、/100の商と余りに分けて、上のを呼び、合成。
自分で書いたのはこんな当たり前の奴だなあ・・・
507:デフォルトの名無しさん
07/11/10 16:03:38
しばらく前はメモリアクセスがからむテーブル参照の方が重いって話だったけど、
また状況変った?
508:デフォルトの名無しさん
07/11/10 16:47:46
キャッシュの容量
メモリアクセス速度とキャッシュアクセス速度の比率
によって変わるからなあ
細かくいいだすとキャッシュ方式も絡むし
結局「場合による」んじゃねえの
509:デフォルトの名無しさん
07/11/10 17:28:19
一般論としては、キャッシュに載っている(=頻繁に呼ばれる)ならテーブルの方が速いんじゃないかね。
ただ、この場合の「一般」というのは、分岐が含まれる(=分岐ミスの可能性がある)という前提。
例えば上の((bin/16)<<4) | (bin%16) の場合だと
依存関係が2箇所あって、その部分は同時実行は出来ないけど
キャッシュアクセスに要する数クロック程度の時間と比べてどちらが速いかはわからんね。
テーブルジャンプ(ほぼ同じ値が続く場合以外)は糞だけど。
510:デフォルトの名無しさん
07/11/10 17:37:19
掛けたり割ったりすることにものすごい抵抗感がある
511:デフォルトの名無しさん
07/11/10 18:06:01
いや、この場合に限れば、まず間違いなく最適化でシフトやアンドになるよ。
512:506
07/11/11 02:32:03
今のチップで乗除算持ってないほうが珍しいよね。俺が書いたのは3MHzの8085だったから、
キャッシュ云々の話はなし。/100だけは除算ルーチン使わないとだめだった。
513:デフォルトの名無しさん
07/11/11 13:44:02
ARMは現役のチップだけど除算命令なかったような
514:デフォルトの名無しさん
07/11/14 11:40:49
x/100 は 掛け算があるなら
655*( x + x/2048 + x/16384)/ 65536
515:デフォルトの名無しさん
07/11/14 14:14:26
その掛け算とシフトの計算量なら、100=64hだから、分母の<<2と<<5と<<6を引いたほうが・・・
516:デフォルトの名無しさん
07/11/14 15:57:51
y = (655*x)>>16 で概算して
while ( x-y*100>=100 ) y++;
ならせいぜいループ1回だろ
517:デフォルトの名無しさん
07/11/14 18:05:59
最低でもx<6557202(≒(1<<32)/655)が言えなければ。
518:デフォルトの名無しさん
07/11/14 18:34:29
>>512
(42949672*x+65536)>>32
519:デフォルトの名無しさん
07/11/15 07:36:11
シフト演算子がアンカーになってしまう(w
>>514-516 は、たぶん数学的には同等なような気がする。
>>518 それ、どういう原理なの? 32シフトしたら全部なくなっちゃうような気が・・・
520:デフォルトの名無しさん
07/11/15 08:53:19
32bitレジスタ持ってるような16bit以上のCPUを想定してるんだろ
x386なら32x32bit掛け算の結果が2つのレジスタに判られるから 32bitシフトは上位のレジスタを採用するだけになる。
521:デフォルトの名無しさん
07/11/15 11:57:03
>>32
>>32
522:デフォルトの名無しさん
07/11/15 12:18:01
>>512
>>32
523:デフォルトの名無しさん
07/11/15 12:22:04
>>521
>>522
何が言いたいのか意味不明だ。
524:デフォルトの名無しさん
07/11/15 12:29:42
>>523
525:デフォルトの名無しさん
07/11/15 12:42:20
これでどうだ
x >> 32
526:デフォルトの名無しさん
07/11/15 12:44:23
俺他人だけど >>523 色が違うだろって言いたいんじゃないのかな?
527:デフォルトの名無しさん
07/11/15 13:11:18
>>523
こうすればいいのよ(たぶん)
528:527
07/11/15 13:12:44
>>527
吊ってくるorz
529:518
07/11/15 16:36:17
>>520
あたり。
あと、>>518のxは0〜65535の範囲である必要がある。
530:デフォルトの名無しさん
07/11/15 16:54:12
多少ステップ数がかかるように見えても、まだハードウエア除算は普通の命令20個分以上に重いからな
1/100 は1/10のルーチンを2度呼んでたな。
1/10は1/2/5 だから1ビットシフトしてから5で割る
65536/5=13107.2 だから13107を係数に使うと誤差は16bitの範囲で1
だけど1ビットシフトしてるから、15bitの範囲になってるから 最大誤差は0.5なんでOK
という事で、最大誤差の0.5を足して
x = x / 2
x = (13107*x+ 6553) / 2^16
を2度繰り返す
531:デフォルトの名無しさん
07/11/16 01:35:07
>>518 や、>>530 は余りも一緒に求まるの?
532:デフォルトの名無しさん
07/11/16 08:46:49
この話は掛け算が高速ならという話だから
余りは後から y=x/N を求めた後 x-N*y で求めればいい
余りだけが必要なら355付近から話題が出てる
533:デフォルトの名無しさん
07/11/16 09:53:08
実測で、ハードウェアまたはCの除算を上回るルーチン作れるの?うpして
動かしてみる辛さ
534:デフォルトの名無しさん
07/11/16 10:26:25
どっかのスレでやってたでしょ。
パソコンの除算命令はレイテンシが大きいから連続して実行させるととても重くなる。
ただ整数ユニットでは実行されないから、その間に他の命令を入れられるならOK
あ、このスレか、>>367-379
535:デフォルトの名無しさん
07/11/16 10:59:28
int型の除算で標準のものより速いものは作れるのか作れないのか?
536:デフォルトの名無しさん
07/11/16 11:03:08
分母が固定なら可能。 変数なら無理。
537:デフォルトの名無しさん
07/11/16 11:04:47
まてよ。分子が固定な場合、ニュートン法である程度いけるかな・・・・まあ無理か
538:デフォルトの名無しさん
07/11/16 11:23:21
分母が固定ならif文などで分岐すれば、総合的には速度が上げられるのか?
作ってくれ
539:デフォルトの名無しさん
07/11/16 11:26:26
経験上、演算や比較文より代入に時間がかかる気がする
たぶんレジスタ動作 + 演算より、メモリ動作は遅いんだろう
540:518
07/11/16 11:39:24
>>535
ループの中で定数(変数でも変わらなければOK)で除算するのは、
置き換えた方が高速化できるし、それを実際に使っている。
ピクセル操作のような回数の多いループでは劇的な効果がある。
>>539
それは毎回キャッシュから外れた場合の話。
オンキャッシュなら少しでもCPUを止めない方がいい。
541:デフォルトの名無しさん
07/11/16 11:45:08
>>538
で、分母はいくらなの? 100の場合はいろいろ出てるよね。
542:デフォルトの名無しさん
07/11/16 11:46:27
汎用の除算は出来ないか?
例えば2〜500まで定数だけ作って分岐させて使う
そのとき高速になるのか?
543:デフォルトの名無しさん
07/11/16 11:48:53
その分岐の為に時間を使ってしまうから無理だろうね
たとえば関数テーブルで分岐したとしても、キャッシュミスを起こすだろう。
544:518
07/11/16 11:50:14
>>542
できる。
それぐらいなら除数の逆数のテーブルを使って可能。分岐はさせないほうがいい。
ただ、16bit全域とかになると、テーブルの方が不利になるCPUが多い。
545:デフォルトの名無しさん
07/11/16 11:54:52
逆数で気づいたけど、浮動小数点の掛け算で計算すると鈍いの?
546:デフォルトの名無しさん
07/11/16 11:57:24
逆数の2進展開を持っていたらビット演算できそうだけど・・・どうだろ 速いのか?
547:デフォルトの名無しさん
07/11/16 12:00:46
たびたび連投すまんが、計算でループを使うなら、はじめに分岐させてもコストは同じようなものだな
2〜1024までなら10回の分岐で決定する 10回程度のループを使うなら分岐させた方が良い
548:デフォルトの名無しさん
07/11/16 12:01:09
>>544
(A*x+B)のA,Bをテーブルにするの?
でも、たとえば 65535÷3はどうするの?A=21845にしたら、これでは無理だよね
549:デフォルトの名無しさん
07/11/16 12:10:41
x / n = (Ax + B ) >> C ってどうやって求めるの?
550:518
07/11/16 12:12:05
>>548
そうそう。Bは固定でいい。
16ビット範囲の X / Dなら、R = 4294967295 / D として、
X / D の値は (R * X + 65536) >> 32となる。
Dが複数あるなら、D→Rのテーブルを作ればOK
551:デフォルトの名無しさん
07/11/16 12:14:16
>>550
BCC5.5だけど、上のやつ計算できなかったよ
552:518
07/11/16 12:19:40
>>551
__asm{
mov eax, R
mul X
add eax, 010000h
adc edx, 0
mov eax, edx
}
553:デフォルトの名無しさん
07/11/16 13:04:33
>>550
Rが切り捨てなら汎用になるように
(R * X + R - 1 ) >> 32
でいいんじゃないの?
554:518
07/11/16 13:09:18
>>553
65536より、R - 1のがいい理由は何?
555:デフォルトの名無しさん
07/11/16 13:24:06
理由は、Xが16bitの範囲を超えて入力された時の誤差が多少でも減る事だな
556:518
07/11/16 13:36:17
>>555
誤差が許される場合はいいかもね。
そうでない場合は、素直に32ビットに拡張した方が良くないか?
557:デフォルトの名無しさん
07/11/16 14:03:01
ようするに
(A * x + A-1 ) >> B
として AのMSBが1になるように B を調整するって事だよね?
Bは常に32以上だから、実際には上位ワードだけを>>(B-32) するのだろうけど
558:518
07/11/16 17:10:53
>>557
いや、そうじゃなくて、余計なA - 1 という演算を使うのではなく、
550の式を32ビットに拡張すればいいってこと。
32ビット範囲の X / Dなら、R = ((1 << 64) - 1) / D として、
X / D の値は (R * X + (1 << 32)) >> 64となる。
559:デフォルトの名無しさん
07/11/17 04:25:26
>>530
ルネサスのマニュアルによるとシフト演算と割り算に迷ったら割り算の方が大抵速いみたいなことが書いてあったけど
560:デフォルトの名無しさん
07/11/17 07:26:50
>>558 さすがに64bit掛算はまだ普及してないだろ
561:デフォルトの名無しさん
07/11/17 07:28:20
>>559 SHが特殊で固定シフト命令が1,2,4,8みたいな飛び飛びのシフトしか1命令で出来なかったりするからじゃないの?
562:デフォルトの名無しさん
07/11/17 12:16:14
でも、仕事で使用するとしたら、普通に割り算したほうがソースとして見やすいよね。
2で割るのを1ビットシフトするぐらいはいいけど、あえて複雑な演算にするほど処理能力を求められないでしょ?普通の開発は。
でも、このような議論って技術者としては面白いし、ある意味大切だよね。
563:デフォルトの名無しさん
07/11/17 12:40:03
>>560
アルゴリズム上の話で、実際に64bit乗算をするわけではないと思う。
元ネタはこれじゃね?
URLリンク(www.emit.jp)
564:デフォルトの名無しさん
07/11/17 13:51:33
>>560
コンパイラがやってくれることもしばしば。
まぁ尤も、コンパイラのアセンブリ出力を見たときに「割り算がない」って悩まないためにも
知識はあったほうがいいのだけれどね。
565:デフォルトの名無しさん
07/11/17 13:57:31
Y = (R * X ) >> 64 って事は 、R = 2^64 / D って事だろ?
Dが16bitの範囲なら Rは 48bitって事になるぞ。 64bitモードに以降しないと効率悪いぞ
566:デフォルトの名無しさん
07/11/17 14:00:28
もともと
D=100の場合
1 : ( x * 4294967200 + 65536) >> 32
2 : ( x * 4294967200 + 4294967199 >> 32
のどっちが 大きな x までまともに計算出来るかって問題でしょ?
567:デフォルトの名無しさん
07/11/17 14:01:49
違うか
1 : ( x * 42949672 + 65536 ) >> 32
2 : ( x * 42949672 + 42949671 ) >> 32
568:デフォルトの名無しさん
07/11/17 15:24:56
BCCで出来ないんだけど・・・CPUのせいかもしれない
内部で32+24ビット程度しか保持していない気がする
569:デフォルトの名無しさん
07/11/17 15:33:51
>>518がちゃんとうごくぱそこんってあるの?
テストプログラム作ったけど上位1ビットの値は壊れているようだ
#include <iostream>
using namespace std;
main(){
int n;
for(n=50;n<=64;n++)
cout<<n<<" "<<(unsigned int)((1<<n)>>(n-1))<<endl;
}
570:デフォルトの名無しさん
07/11/17 15:43:45
これっていくつになりますか?
1になるはずですよね?
cout << (unsigned int) ( ((1<<64)-2) >> 63 );
571:デフォルトの名無しさん
07/11/17 17:43:47
>>570
-1を unsigned にキャストしてるんだからUINT_MAXになると思う。
572:デフォルトの名無しさん
07/11/17 18:06:10
符号付整数の右シフトが論理シフトになるか算術シフトになるかは処理系定義
573:ヽ・´∀`・,,)っ━━━━━━┓
07/11/17 19:18:14
>>569
unsigned __int64かunsigned long longでおk
574:ヽ・´∀`・,,)っ━━━━━━┓
07/11/17 19:20:40
>>570
なんで普通のコンピュータで使えるビット数越えたシフト使うんだ。
1 << 64なんてオーバーフローで0になること確定じゃないか。
575:デフォルトの名無しさん
07/11/17 20:42:48
~0ULLでおk
576:デフォルトの名無しさん
07/11/17 23:58:43
>>569
>>563のコードと同じだからそっちでやってみればいいんじゃないか。
577:デフォルトの名無しさん
07/11/18 07:54:51
#include <iostream>
using namespace std;
main(){
unsigned int n;
for(n=60;n<64;n++)
cout<<n<<" "<<(unsigned int)(((1<<n)-2)>>(n-1))<<endl;
cout<<63<<" "<<(unsigned int) ( ((1<<63)-2) >> 62 );
}
63の値が変わるのはなぜ?
578:デフォルトの名無しさん
07/11/18 08:34:36
>>577
サイズを超えるシフトは未定義。
579:デフォルトの名無しさん
07/11/18 22:48:23
ARMは割り算使うと糞遅いから困るな。
580:デフォルトの名無しさん
07/12/03 22:55:09
age
581:デフォルトの名無しさん
07/12/03 23:13:14
32bitパソコンだと、16*16しか値は保証されないよね
a + b * 65536 などと表示して、32bit以上を表現したら
ハードウェア搭載の除算よりビット演算のほうが速い?
除算が現れたらintを16bit数に変換して計算する
582:デフォルトの名無しさん
07/12/04 05:02:29
X = 65536 、R = 1/Xとすると
(a+bX) / (c+dX) = (b+aR) / (d+cR)であり、
1/(1+R) のテイラー展開は、 1 - R + R^2 - ・・・+(-R)^n+ ・・・
Rの巾は非常に小さいため2乗までを採用すると、
(a+bX) / (c+dX) = ( (b+aR)/d ) * 1/(1 + cR/d)
=( (b+aR)/d ) * (1 - cR/d + (cR/d)^2 )
=1/(X^3 * d^3) * (a + bX ) * (c^2 -cdX + d^2X^2 ) となる
これで32bit除法を高速化出来るか?
583:582
07/12/04 05:12:33
32bit内で処理しようとすると大変だ 普通にCPUに任せた方が楽そう
584:デフォルトの名無しさん
07/12/16 20:25:38
BOOL bResultの値が 0 か -1
if (bResult == 0 || bResult == -1)
じゃなくて、一発で調べる方法はないですか?
585:デフォルトの名無しさん
07/12/16 20:42:35
BOOLなのに何故数値と比較してるんだ?
586:デフォルトの名無しさん
07/12/16 21:10:40
GetMessageじゃね?
587:デフォルトの名無しさん
07/12/16 21:30:22
BOOLは偽==0、真==0以外じゃなかったか?
定義を調べた方が良さそう。
588:デフォルトの名無しさん
07/12/16 22:05:41
世の中には変な使い方する椰子がいるのよ。MSとかw
URLリンク(msdn.microsoft.com)
589:デフォルトの名無しさん
07/12/16 22:08:46
if(bResult^0==-1)
590:デフォルトの名無しさん
07/12/16 22:37:38
x^0=x
591:デフォルトの名無しさん
07/12/16 22:42:19
if (((((uint32_t)bResult) + 1) >> 1) == 0)
同じ3演算だけど-1をロードしないだけ早いかも?
uint32_tがいいかどうかはよくわからない。
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5388日前に更新/206 KB
担当:undef