07/06/20 12:26:09
>>342
たとえば、機械類なんかの位置あわせの目的で センサーを配置する時に
4入力あれば16箇所の位置を特定できるわけだけど
同時に2つのセンサーが変化するようになってると巧くゆかない。
そこで移動につれて、一つしかセンサーが変化しないような配置方法を考えたのがそのコード。
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がいいかどうかはよくわからない。
592:デフォルトの名無しさん
07/12/17 00:16:01
-1か0、限定なんだからそのまま書いたほうが分かりやすいような。
593:デフォルトの名無しさん
07/12/17 00:26:58
>>588
( ・д⊂ヽ゛
594:デフォルトの名無しさん
07/12/17 00:29:32
>>588
>警告 GetMessage 関数は、0 以外の値、0、-1 のいずれかを返します。したがって、次のようなコードは避けてください。
そもそも…
595:デフォルトの名無しさん
07/12/17 00:30:54
まー継ぎ接ぎだからな
596:デフォルトの名無しさん
07/12/17 00:39:34
>>591
右シフト・条件分岐より、比較・条件分岐の方が速くない?
if (((uint32_t)bResult + 1) <= 1)
597:デフォルトの名無しさん
07/12/17 00:50:04
>>596
マシン語レベルでは結局0比較に変換されるから同じ程度じゃないかな。
でもCレベルではそっちの方が短くていいと思う。
598:デフォルトの名無しさん
07/12/17 01:17:11
>>597
ちょっと前まで主流だった某CPUではシフトは加減算の
8倍遅かったし、それ以外のCPUでも演算器の関係で
シフトの方が並列化されにくいかも、とかそういう話。
599:デフォルトの名無しさん
07/12/17 01:19:21
で、何億回呼ぶのよ
600:デフォルトの名無しさん
07/12/17 02:05:25
シフトのほうが速いと思ってたのに・・・
601:デフォルトの名無しさん
07/12/17 03:12:30
>>599
そんなこと言うならこのスレの意義って一体なんなのさ。
確かにWindows APIをそんなアホみたいに呼ぶ事はないだろうが、
こんな風に一般化してみれば、それなりに使い道はあるだろ。
_Bool bounds_check(int n, int lower, int upper)
{
return (unsigned)(n - lower) < (unsigned)(upper - lower);
}
>>600
加減算よりシフトの方が速いCPUなんてあるのかな?
演算の頻度からいっても普通は加減算を最速に設計すると思うけど。
x86系を数種類しか触った事ないから、他にはあるのかも知れないが。
602:デフォルトの名無しさん
07/12/17 04:47:19
ハードウェアの構造上加減算よりシフトの方が圧倒的に単純なんだよ
小さい加算器を作ったことがあればわかるはず
クロック数が一緒ってことはあるかもしれんが、
シフトの方が遅いってことはまずないだろう
603:ヽ・´∀`・,,)っ━━━━━━┓
07/12/17 05:39:05
ARMだと全命令にプレディケーション使えるからCレベルの単純な分岐は直列化できるよ
分岐は極端に遅いなんていうのはCellプログラマだけにしてください。
604:デフォルトの名無しさん
07/12/17 07:41:05
>>602
このケースは1bitだからその通りだけど
x86の8086-286までは、2bit以上のシフトは遅かったんだよ。
最初は直接bit数指定のインストラクションすらなかったし。
605:デフォルトの名無しさん
07/12/17 13:11:19
URLリンク(answers.google.com)
606:デフォルトの名無しさん
07/12/17 13:13:10
>>603
単純な分岐なら、if文使ってコンパイラに任せた方が速いね。
絶対値求める時とか、NULLならreturnするとか、分岐コストかからなくていい。
607:デフォルトの名無しさん
07/12/17 14:37:02
むしろif文にbool型しかとらないJava/C#が異端なんじゃねーの?
俺もbool型オンリーの方が好きだが、スクリプト言語してるとそうじゃない方が多い気がする。
608:デフォルトの名無しさん
07/12/17 18:27:51
ifの選択肢にTrueとFalse以外なんてあり得るの?
609:デフォルトの名無しさん
07/12/17 18:33:36
if(666){//実行されます。}
610:デフォルトの名無しさん
07/12/17 19:02:56
コメントに括弧閉じ書いて意味あんの
611:デフォルトの名無しさん
07/12/17 21:34:17
if (GetMessage(...) <= 0)
で充分でね?
612:デフォルトの名無しさん
07/12/17 21:49:47
>>602
シフタってのはデータセレクタの塊だから多ビットのシフトは
シリコンの面積を喰うのよ
613:デフォルトの名無しさん
07/12/17 23:54:21
>>611
-1以外の負の値が未定義
614:デフォルトの名無しさん
07/12/17 23:54:34
シフタのないプロセッサには出会ったことが無いけどね。
615:デフォルトの名無しさん
07/12/17 23:58:16
if (bResult == 0 || bResult == -1)
は
if (((uint32_t)bResult + 1) <= 1)
と同じコードになったぞ。
gcc賢いな。
ちなにみRISCでどうなるか見たかったので団子の嫌いなCELLのgccでコンパイルしたw
ちなみにCELL(SPE)もヒントブランチあるから。
むしろARMのプリディケーションいまいちだと思うけど。
616:ヽ・´∀`・,,)っ━━━━━━┓
07/12/18 00:11:17
知ってるが
Cellのスカラ性能が
気に食わない
617:ヽ・´∀`・,,)っ━━━━━━┓
07/12/18 00:45:11
分岐ヒントもBranchの15クロックくらい前くらいに入れないと駄目じゃなかったっけ
しかも二重に使うとハングする致命的なバグ持ちだから始末に困る
618:デフォルトの名無しさん
07/12/18 00:47:47
if (bResult == 0 || bResult == -1) こんなん対して食わないだろ゜
619:ヽ・´∀`・,,)っ━━━━━━┓
07/12/18 00:52:15
SSE4.1のXMMに対する比較命令が加わったから4条件同時判定とかも便利そうだね
620:デフォルトの名無しさん
07/12/18 08:10:08
ダンゴさんが連投するとスレが引き締まるな
621:デフォルトの名無しさん
07/12/18 11:30:40
ダンゴage
622:デフォルトの名無しさん
07/12/18 20:46:31
test
623:デフォルトの名無しさん
07/12/21 07:08:36
test
624:デフォルトの名無しさん
07/12/21 07:18:07
URLリンク(www.nicovideo.jp)
625:デフォルトの名無しさん
07/12/30 10:37:00
年末あげ
626:デフォルトの名無しさん
08/01/03 18:36:52
URLリンク(itl.jisakuita.net)
ダンゴさんすげえな
627:デフォルトの名無しさん
08/01/09 19:20:08
sge
628:デフォルトの名無しさん
08/01/14 22:47:23
V(・∀・)V
629:デフォルトの名無しさん
08/01/21 23:54:19
あげ
630:デフォルトの名無しさん
08/01/22 00:09:06
以下の2つの値があったとします。
x1 = 0xFF842144
x2 = 0x5400FF33
ユーザからの入力u1、u2が入力された場合
考えられるケースは以下の4つになると思います。
・u1=x1、u2=x2一致
・u1=x1一致
・u2=x2一致
・どちらとも一致しない
最低3回比較しないとどのケースか判断できないって
思い込んでるのですが
何かいいアイディアくれる人いませんか?
631:デフォルトの名無しさん
08/01/22 00:46:32
愚問だと思いますが。。
しかし、そんあ80年代前半のBASICの論理式みたいなアナクロな発想をするって
今日日奇特な人だね。
632:デフォルトの名無しさん
08/01/22 00:50:58
u1がx1と一致するケースに
・u1=x1一致、u2=x2一致
・u1=x1一致、u2=x2不一致
がある
u1がx1と一致しないケースに
・u1=x1不一致、u2=x2一致
・u1=x1不一致、u2=x2不一致
がある
つまり4通り
比較は最大2回
633:デフォルトの名無しさん
08/01/22 01:21:29
その比較を10^12回通りくらい計算するつもりなら最適化もあり
634:デフォルトの名無しさん
08/01/22 01:30:35
あらかじめ
p = x1 XOR x2
の値を取得しておく
q1 = p XOR u1
q2 = p XOR u2
を得る
635:ヽ・´∀`・,,)っ━━━━━━┓
08/01/22 01:30:56
SSE4のptest使えば一回で済む
636:デフォルトの名無しさん
08/01/22 01:54:14
>>634
得た後はどうすればいいのw?
q1とq2をどうやって使うの?
637:デフォルトの名無しさん
08/01/22 02:56:20
>>632
>・u1=x1一致、u2=x2一致
あんた馬鹿?
638:デフォルトの名無しさん
08/01/22 11:10:15
>>635
無理だろ,あれは and と andnot だから.pcmpeqd の方が良さげ
639:デフォルトの名無しさん
08/01/22 11:49:49
632ってこういうことだろ?
if( u1 == x1 ) {
if( u2 == x2 ) {
//ryouhou
} else {
//u1 nomi
}
} else {// not
if( u2 == x2 ) {
//u2 nomi
} else {
//ryouhou itti sinai
}
}
どこも間違ってるように思えないんだが。
640:デフォルトの名無しさん
08/01/22 12:34:57
しかし、BY(文脈読めない)な奴が多いな。
ここがどういうスレかを考えれば、>>630が何を聞きたいか
多少説明不足でもだいたい分かるだろ普通w
641:デフォルトの名無しさん
08/01/22 13:13:10
ほうほう。それでそれで?
642:デフォルトの名無しさん
08/01/22 18:32:50
int a[] = {両方一致, 片方一致, 片方一致, 一致しない};
b1 = (u1 == x1)
b2 = (u2 == x2)
return a[(b1 << 1) | b2];
643:642
08/01/22 18:33:45
× int a[] = {両方一致, 片方一致, 片方一致, 一致しない};
○ int a[] = {一致しない, 片方一致, 片方一致, 両方一致};
644:デフォルトの名無しさん
08/01/23 10:32:39
ゼロフラグでレジスタに0,1をセットする命令があるならソレが効率的だね。
それがないと、減算して、さらに1引いてキャリーを出してローテートしなくちゃいけない
アキュムレータが2個しかないCPUなら
AccA := u1-x1-1;
RotWithC(AccB);
AccA := AccA+x1+1-x2-1;
RotWithC(AccB);
AccB := AccB and 3;
結局、そのあたり何が効率的かはアセンブラで見ないといけないけど
アセンブラで出来る高速化は、リニアにしか効かないから、そんなに意味ないんだよね
645:デフォルトの名無しさん
08/01/23 20:55:34
全面的に同意.ただ2倍位速くなることもあるから最後の手としては有効.まぁ今は可能 intrinsic 使うけど.
646:デフォルトの名無しさん
08/01/23 21:06:35
割り算を掛け算とビットシフトに置き換える計算式求めるプログラムできた
#include <iostream>
using namespace std;
main(){
unsigned int N,n,k;
for(N=2; N<65000 ; N++){
for(n=0; (1<<n)<N ; n++); n+=15;
double X=(pow(2,n)/N);
unsigned int Y=(unsigned int)X;
unsigned int d=0;
if(X-Y<=Y+1-X)d=(unsigned int)(pow(2,n)- (N-1)*Y)-1; else Y++;
printf("x /%5d = ( x * %5d + %5d ) >> %2d",N,Y,d,n);
for(k=1; k<(1<<16) ; k++) if(k/N != ((k*Y+d)>>n))break;
if(k==(1<<16))printf(" OK\n"); else printf(" ERR\n");
}}
647:646
08/01/24 15:42:18
64bit機か、内部で64bitまで計算結果を保持しているなら
32bitの割り算も出来るけど646は16bit同士です
648:デフォルトの名無しさん
08/01/24 15:52:26
GCC の中見りゃあるんじゃね?
649:デフォルトの名無しさん
08/01/24 17:46:02
>>648
gcc のカオス・スパゲッティ状態を知らぬようだな。
勧めるならせめて Small-C くらいにしとけ。
このルーチンなら 工学社から出ていた
Small-C ハンドブックにもちゃんと説明されていたんだし。
650:デフォルトの名無しさん
08/02/04 20:42:37
ハッカーの楽しみ買ってきました~
これから読みますノシ
651:デフォルトの名無しさん
08/02/05 23:53:51
Hacker's Delight やっと届いた
652:ヽ・´∀`・,,)っ━━━━━━┓
08/02/06 01:12:31
俺もアレ訳本出る前ネットショップで買ったわ
653:デフォルトの名無しさん
08/02/22 06:50:56
a
654:デフォルトの名無しさん
08/02/28 07:49:51
a
655:デフォルトの名無しさん
08/03/01 13:50:55
a << 1
656:デフォルトの名無しさん
08/03/05 07:05:43
a
657:デフォルトの名無しさん
08/03/11 07:43:25
あげ
658:デフォルトの名無しさん
08/03/24 22:44:22
あげ
659:デフォルトの名無しさん
08/03/30 21:00:53
あげ
660:デフォルトの名無しさん
08/03/30 21:42:47
なにこのスレきもい。
でも懐かしい。
661:デフォルトの名無しさん
08/04/06 18:17:38
|
|
/ ̄ ̄ ̄ ̄ ̄ ̄
<⌒/ヽ-、___
/<_/____/
662:デフォルトの名無しさん
08/04/06 18:41:01
ダンゴさんを称えるスレというわけではありませんが、まあ、KY。
663:デフォルトの名無しさん
08/04/06 19:46:30
GCAの作者のページにビット演算が載ってたけど今いちわからん
664:デフォルトの名無しさん
08/04/07 17:04:46
ViViの作者のページにもビット演算が載ってたけどだいたい理解した
URLリンク(vivi.dyndns.org)
665:デフォルトの名無しさん
08/04/07 19:44:18
>配列による状態表現よりも処理が高速になる場合が多い
この表現は凶悪だな。何故なら、高速にならなかった場合にはかなり遅くなる可能性があるからだ。
666:デフォルトの名無しさん
08/04/17 06:42:52
age
667:デフォルトの名無しさん
08/05/01 06:01:45
age
668:デフォルトの名無しさん
08/05/01 08:02:29
燃料がないな
669:デフォルトの名無しさん
08/05/01 08:50:52
16bitカラーで 5:5:5 とか 5:6:5 とか の時代なら色々やったけどな
670:ヽ・´∀`・,,)っ━━━━━━┓
08/05/01 18:55:25
AltiVecにも16bitカラー用の演算があったな
671:デフォルトの名無しさん
08/05/09 19:08:22
こちらのスレから誘導されて参りました。よろしくお願いします。
スレ立てるまでもない質問はここで 第91刷
スレリンク(tech板:171番)
以下の条件で、32bit値のハミングウェイトが素数か否かを判定する
出来るだけ高速な方法を探しています
・入力はランダム
・(最悪ではなく)平均速度が速いことが望ましい
・0、1は素数ではない(偽になって欲しい)
・ハミングウェイトそのものの値は必要ない
・64bit拡張などは必要ない。32bit決め打ちで良い
・外部メモリはあまり使いたくない
皆様のお知恵を貸していただけませんでしょうか
672:デフォルトの名無しさん
08/05/09 19:25:44
一応、今はこんな感じです
ベタな実装で恥ずかしいですが…
int hw_is_prime(unsigned long x)
{
x = ( (x & 0xAAAAAAAA) >> 1 ) + (x & 0x55555555) ;
x = ( (x & 0xCCCCCCCC) >> 2 ) + (x & 0x33333333) ;
x = ( (x & 0xF0F0F0F0) >> 4 ) + (x & 0x0F0F0F0F) ;
x = ( (x & 0xFF00FF00) >> 8 ) + (x & 0x00FF00FF) ;
x = ( (x & 0xFFFF0000) >> 16) + (x & 0x0000FFFF) ;
return (1 << x) & 0xA08A28AC;
}
673:デフォルトの名無しさん
08/05/09 21:56:14
1 << 32 の結果って決まってたっけ
674:デフォルトの名無しさん
08/05/12 10:32:41
処理系定義かな。0ビットシフトになる場合と32ビットシフトになる場合が一般的だと思う。
675:デフォルトの名無しさん
08/05/12 18:51:02
まぁ 8bit, 16bit, 32bit が int の場合と、
64bit が int の場合では結果は明らかに異なるよな
676:デフォルトの名無しさん
08/05/12 20:19:59
8bitがintになることってありえるっけ
677:デフォルトの名無しさん
08/05/12 20:51:31
規格は一応-32767~32767だからないんじゃね?
678:ヽ・´∀`・,,)っ━━━━━━┓
08/05/12 21:34:45
1ビットマシンとか4ビットマシンとかってCでプログラミング可能なの?
679:デフォルトの名無しさん
08/05/12 21:44:21
CHAR_BIT >= 8 だけど、
別に変数1つをレジスタ1つで扱えないといけないわけじゃないし
問題ないんじゃね?
680:デフォルトの名無しさん
08/05/12 21:47:55
ダンゴさんのカキコでスレが加熱したな
681:ヽ・´∀`・,,)っ━━━━━━┓
08/05/12 21:59:19
レス番飛んでるな
682:デフォルトの名無しさん
08/05/13 11:50:54
ダとかンとかゴとか入ると飛ぶんだよな。
683:デフォルトの名無しさん
08/05/13 11:56:23
実は見えてる
684:デフォルトの名無しさん
08/05/13 12:39:16
ダンゴって名前を嫌がるのは、
体型が肉団子だからだよな。
685:ヽ・´∀`・,,)っ-○◎●
08/05/13 12:47:46
だんごはこれだろ
━━━┓がどうみたらだんごに見えるねん
あたまわるいんとちゃうか
686:ヽ・´∀`・,,)っ鹵~<巛巛巛
08/05/13 12:50:40
虫除けのようなものだよ
687:デフォルトの名無しさん
08/05/13 14:33:31
ダンゴさんってどんな仕事してるの?
688:デフォルトの名無しさん
08/05/13 16:51:03
名無しさんの書き込みでスレがヒートアップしたな。
689:デフォルトの名無しさん
08/05/13 18:15:31
他愛もない雑談だけどな。
と、だけ書くのもなんだから、ちょこっとマジレス。
ANSI C での int の定義は処理系依存で、CPUのレジスタ幅によるらしい。
なので、Z80 なら 8bit の筈だけど、
大体のZ80 C処理系では char=8bit, int=16bit と扱う。
なんで int は 16bit より大きいという誤解があるんだろうなぁ。
その昔は char=7bit なんで処理系もあったというので、
油断は出来ないように思うんだよ。
690:デフォルトの名無しさん
08/05/13 18:38:03
INT_MINは-32767以下、INT_MAXは+32767以上じゃないといけないと決まってる
昔の話は知らん
691:ヽ・´∀`・,,)っ━━━━━━┓
08/05/13 19:01:17
1ビットCPUは実際にあった
URLリンク(www.d1.dion.ne.jp)
692:デフォルトの名無しさん
08/05/13 21:12:11
昔はやりたい放題だったかも知れないが、
今は規格に準拠した処理系であれば int >= 16 bits なのは真理。
あと、int のサイズの定義は CPU のレジスタ幅にして欲しそうな定義ではあるけど、
そう断言している訳じゃない。
実際最近でも 64-bit マシンで int = 32-bit のことがある。
693: ◆0uxK91AxII
08/05/14 01:14:15
>>689
>その昔は char=7bit なんで処理系もあったというので、
無い。
694: ◆0uxK91AxII
08/05/14 01:21:20
ごめん、間違い。
695:デフォルトの名無しさん
08/05/14 03:04:09
uartと間違えたんだな
696:デフォルトの名無しさん
08/05/14 23:42:41
ハネウェルの昔のマシンとかは 6bit 単位のマシンとかがあったから、
それとの勘違いだろ。(7bit があったかどうかは知らん。)
まあ単位が 6bit なのは uart と同じ理由だが。
697:デフォルトの名無しさん
08/05/15 02:07:52
>>691
それはCPUと言うよりリレーの置き換えみたいなもの
Connection Machineのはまともな1bit CPUだけどbit sliceだから何bitにでも
化ける
698:デフォルトの名無しさん
08/05/28 00:29:01
あげ
699:デフォルトの名無しさん
08/05/30 00:17:23
11100111
こんなビットがあったとき、0が4と5ビット目に
存在するってどうやって調べるのが効率いいのかな?
個数はわかるけど位置はどうすりゃいいんだろう
700:デフォルトの名無しさん
08/05/30 00:34:24
Hacker's Delight 嫁
701:デフォルトの名無しさん
08/05/30 02:40:11
>>699
11100111 and 00011000
702:デフォルトの名無しさん
08/05/30 02:41:22
8bitなら256個のテーブル持てば最速じゃね? 16bit以上なら、シフトして端のbitの0/1と
シフト回数で判別。
703:デフォルトの名無しさん
08/05/30 02:50:48
>>699
ループ
704:デフォルトの名無しさん
08/05/30 09:37:40
>>703
>>701
aビット目とbビット目が動的に変わるなら、マスク作ってandとった方が良いかもしれない。
705:デフォルトの名無しさん
08/05/30 09:47:01
>>699
問題文は正確に
706:デフォルトの名無しさん
08/05/30 11:48:47
>>699
4、5ビット目というのは変わりうるのよね?
あと個数が2個というのも変わりうるのよね?
707:デフォルトの名無しさん
08/05/30 11:51:01
>>699
ああ、あと、いつもがそんな風に左右対称とは限らないのよね?
708:デフォルトの名無しさん
08/05/30 12:36:25
一番下の0のビットだけを1にするのなら
y := ( not x ) and ( x +1)
で出来るから、ビットが1の個数が判る命令BitCount があるんなら
BitCount( y-1 ) で求まるよ
で x:= x or y; として一番下の0だったビットを1にしてから $FF になるまで繰り返せばいい
709:デフォルトの名無しさん
08/06/11 00:25:23
>>708
それって並列にできないですかね
無理ですよね.....
710:デフォルトの名無しさん
08/06/11 00:30:28
bit演算で128、64、32bitを扱う場合
みんなどんなふうに宣言しますか?
C/C++でのバターな方法が解りません
711:デフォルトの名無しさん
08/06/11 00:34:46
まずトラを数匹用意します。
712:デフォルトの名無しさん
08/06/11 00:41:57
あるプログラムで実際にあったコード。
普通ループではカウンタを++していくと思うけど、
(iを1,2,3・・・と加算)
一回処理するごとに左に1ビットシフトしていた。
(iを1,2,4,8・・・とシフト)
普通こういうコード書きます?仕事で。
713:デフォルトの名無しさん
08/06/11 00:49:43
>>712
1989年ぐらいに見た記憶があるw
714:デフォルトの名無しさん
08/06/11 01:15:51
グレイコードを扱うような貧弱なCPUに対するコードなら在り得る。
715:デフォルトの名無しさん
08/06/11 01:26:18
1ビットずつスキャンしていく場合には使う。
716:デフォルトの名無しさん
08/06/11 01:27:14
>>712
普通にあるし、速度面だけでなく、その方が可読性があるものもある。
717:デフォルトの名無しさん
08/06/11 01:28:54
終了条件でいつも悩むんだけどね。
718:デフォルトの名無しさん
08/06/11 07:07:30
for( bit=1 ; bit ; bit<<=1 ) cnt += ( ( data & bit) >0 );
こういうの?
719:デフォルトの名無しさん
08/06/12 22:51:52
アセンブラで1~8回のループをシフト+キャリーでやることはあったな。
720:デフォルトの名無しさん
08/06/12 23:56:44
もしかしたらループ回数が32かいを超えたら・・・
どうするの?
721:デフォルトの名無しさん
08/06/13 08:21:14
>>720
普通にカウントしろよw
722:デフォルトの名無しさん
08/06/13 11:54:06
正直別にどうでもいい
泣くしかない
723:デフォルトの名無しさん
08/06/25 13:20:16
0xC89664
の1バイト目・2バイト目の値を求める方法をお願いします。
724:デフォルトの名無しさん
08/06/25 13:24:45
>>723
貴方の小人は頭から食べるのですか? お尻から食べるのですか?
URLリンク(www.aozora.gr.jp)
725:デフォルトの名無しさん
08/06/25 19:29:14
囲碁(9路盤)のbitboardを作ろうとしています。
9x9なのでSSE2使えば128ビットレジスタ一個に収まるのでかなりの高速化が出来ると思っています。
囲碁のルールに上下左右を全て囲まれた石の塊は盤から取り除かれるというのがありますが、
これを高速に行うにはどうしたらよいでしょうか。
問題はSSE2は128ビットを一塊としたシフトが行えないことで、これのせいでどうしたらよいかわからなくなっています。
よろしくお願いします。
726:デフォルトの名無しさん
08/06/25 19:48:23
モンテカルロ木の実験ですか?
727:デフォルトの名無しさん
08/06/25 20:02:15
>>726
そうです。
モンテカルロはスピード命らしいので、SSEを使えないかと思っています。
728:デフォルトの名無しさん
08/06/25 21:11:08
左シフトなら paddq である程度代用出来るだろ
729:デフォルトの名無しさん
08/06/25 21:49:09
paddqって64ビットの境目で切れ目が出来てしまいませんか。
730:デフォルトの名無しさん
08/06/25 21:53:24
128ビット丸々だとバイト単位の命令しかないからねぇ。
x64環境を使っていいのならビット単位をやめてバイト単位にして
16本のXMMレジスタを9本使って9x9にした方がいいんじゃないかな?
731:デフォルトの名無しさん
08/06/25 22:23:24
それならビット単位でshort[9]でもよさそうですが、
バイト単位にしたほうが有利なんですか?
732:デフォルトの名無しさん
08/06/25 23:18:33
ビット単位で操作できないから困ってたんじゃなかったの?
733:デフォルトの名無しさん
08/06/26 06:48:29
レジスタを9本も使うなら32ビットのレジスタでも9x9の盤は収まってしまいます。
その場合、ビット単位の操作は可能です。
x64でレジスタが16本あったとしても通常のレジスタを9本も占めるというのは考えにくいですが、
XMMレジスタなら9本使っても支障ないということでしょうか?
734:デフォルトの名無しさん
08/06/26 09:01:44
>>729
最大9bitしかシフトしないでしょ? なら 境界にデータを置かなければいいでしょ
あるいは16bitを1列にしてレジスタ2つにしたらどう?
735:デフォルトの名無しさん
08/06/26 10:08:36
>>733
x64で汎用レジスタが増えたとはいえ9本も使えばループや分岐に支障が出ると思うよ。
その点XMMレジスタなら浮動小数点演算しなければ基本的に空いてる。
736:725
08/06/26 19:15:01
725です。
すいません。
皆さんにレスしていただいておいて申し訳ないのですが、
高速化について調べていたらGPGPUというのが見つかりました。
グラボに計算をさせるというものなのですが、上手くツボにはまれば
CPUの何十倍もの速度がでるそうです。
囲碁がはたしてグラボに計算させるのに向いてるのかどうかわかりませんが、
SSEは一旦忘れて、GPGPUについて調べてみようと思います。
グラボも3~4万だせば結構いいのが買えるみたいです。
とりあえずGPGPUスレとCUDAスレにいって雰囲気つかんできます。
皆さんのレスには感謝しています。
失礼しました。
737:デフォルトの名無しさん
08/06/26 19:47:50
そっち行ってもいいならFPGAっていうテもあるかもしれん。
738:デフォルトの名無しさん
08/06/26 21:47:07
5年ほど前にFPGAでオセロの石を返す部分を作ったが
普通にCPUで計算するより遅かった
739:デフォルトの名無しさん
08/06/26 22:43:05
>>736
CUDAするなら前もって、GPUに計算させたい部分
設計しておけ
わしは今日から3日でモンテカルロをCUDAで解けるように
勉強する
740:725
08/06/27 00:03:02
>>739
どもです。
ところで最新ハイエンドGPUはピーク性能1TFLOPS超えるらしいですね。
HDDもテラバイトの物が出てるし、時代はもうテラなんですねぇ。
741:デフォルトの名無しさん
08/06/27 00:18:19
>>740
Radeon HD3870とGeforce9800GTXもってるけど
両方とも労せず2000スレッド以上生成して並列に計算できるよ
742:デフォルトの名無しさん
08/06/27 00:32:16
>>725
一命令ではできないが,シフトしたいビット数を n として n/8 と n%8
とに分けてシフト命令使って後で合成すれば可能
743:デフォルトの名無しさん
08/06/27 04:00:39
>>738
enumの様に贅沢にintを丸々一つ石に配分した方が良かったかもしれないね。
744:デフォルトの名無しさん
08/06/27 07:18:19
ベクトル演算を利用するなら 閉曲線の内側か外側の判定で巻付判定法を応用するといいように思うな
ビット演算じゃないけど
745:デフォルトの名無しさん
08/07/11 01:01:51
あげ
746:デフォルトの名無しさん
08/07/20 15:56:27
う
747:デフォルトの名無しさん
08/07/20 20:41:05
今どきビット演算で高速化とかw
748:デフォルトの名無しさん
08/07/20 23:07:22
プログラミングマニュアル1・基本仕様ガイド
の
・式
ってとこに詳しく書いてるだろ...読みもしないで不思議とか言うな
749:デフォルトの名無しさん
08/07/20 23:07:59
誤爆すいません
750:デフォルトの名無しさん
08/07/22 10:17:23
こやつめ!
751:デフォルトの名無しさん
08/08/01 03:07:44
2^a を渡されたときaを求める方法で何かいい物はありませんか?
なるべくループやlogを使わない物がいいです
752:750
08/08/01 03:26:58
>>751
追記、1≦a≦9
753:デフォルトの名無しさん
08/08/01 03:27:44
>>752
自分の名前間違えた>>750じゃなくて>>751
754:デフォルトの名無しさん
08/08/01 04:04:46
513個の配列持って、その中に1~9を入れておく。[1]=なし、[2]=1、[3]=なし、[4]=2、・・・
[512]=9 演算はこれが最速。
755:デフォルトの名無しさん
08/08/01 04:06:47
サイズが問題なら、
if( n & 0x200 ) return 9;
if( n & 0x100 ) return 8;
・・・
if( n & 0x002 ) return 1;
756:デフォルトの名無しさん
08/08/01 04:15:16
x86ならBSF
757:デフォルトの名無しさん
08/08/01 04:39:50
char bit[256] = {1,2,0,3,0,0,0,4, 略 };
bsf(int n) {
int r;
if ((r = bit[n&255])) return r;
n >>= 8;
if ((r = bit[n&255])) return r + 8;
n >>= 8;
if ((r = bit[n&255])) return r + 16;
n >>= 8;
if ((r = bit[n&255])) return r + 24;
return 0; //解なし
}
758:デフォルトの名無しさん
08/08/01 04:41:33
こんなのどうよ?
bsf(bits){
bits-=1;
int num;
num = (bits >> 1) & 03333333333;
num = bits - num - ((num >> 1) & 03333333333);
num = ((num + (num >> 3)) & 0707070707) % 077;
return num;
}
759:デフォルトの名無しさん
08/08/01 04:52:26
>>754-758
ありがとうございます。みんなカッコイイ
760:デフォルトの名無しさん
08/08/01 05:52:52
>>757は
char bit[256] = { 0,1,2,0,3,0,0,0, 4,0,0,0,0,0,0,0, 略 };
の間違いだった。
んで結果を-1すれば合うんじゃないかな。
761:デフォルトの名無しさん
08/08/01 06:23:57
こんなんでどよ
int f(unsigned n){
int a=1;
unsigned b;
n>>=2;
b = n>>4;if(b)a+=4,n=b;
b = n>>2;if(b)a+=2,n=b;
return a+n;
}
762:デフォルトの名無しさん
08/08/01 10:45:43
"_\0\5\1\10\6\2__\4\7_\3"[n*0xCA030FF>>28];
763:デフォルトの名無しさん
08/08/01 14:50:59
お前頭いいなー、でも
"_\1\6\2\011\7\3__\5\010_\4"
じゃないか
もう少し小さいハッシュもあった
"\1\2\3\010\6\4\011__\7\5"[n*0x5300000>>28];
764:762
08/08/01 16:32:34
あー間違えてたーthx
そしてそっちのハッシュのほうが優れているね。
765:デフォルトの名無しさん
08/08/01 16:55:45
なるほど、ハッシュってそういう使い方するんだ。
766:デフォルトの名無しさん
08/08/01 17:47:48
>>762-763
異次元過ぎてついて行けないのだが解説頼む
767:デフォルトの名無しさん
08/08/01 21:25:31
俺もわかってないが
gperfとかで完全ハッシュ関数を作るのと同じように
(文字列ではなく)特定の数字から対応する特定の数値への完全ハッシュ関数を作っているんだと思う。
どうやって導いたかなんて知らん。
768:デフォルトの名無しさん
08/08/02 01:40:13
へええ
左シフトしたときに
あるビット範囲(この例だと28ビット目から31ビット目)が
シフト回数ごとにバラけるようにしているのか
シフト回数 (n*0x5300000)のbit28~31の値
1 0
2 1
3 2
4 5
5 10
6 4
7 9
8 3
9 6
んで配列テーブルをlookupすると。
完全ハッシュ関数って、元が異なれば必ず先が異なる関数のことだっけ。
じゃないとこれ使えないよな。
小さいというのは先の範囲、つまり今回は28~31の4ビットのことか。
確かに小さいほうがメモリとキャッシュに優しいですな。
という感じであってますか。
>どうやって導いたかなんて知らん。
俺も知りたい。
769:デフォルトの名無しさん
08/08/02 01:52:05
頭良すぎる
770:デフォルトの名無しさん
08/08/02 01:56:27
2chってすげーな
771:デフォルトの名無しさん
08/08/02 10:03:58
ビット演算ってたしかにすごいけど、
ソースに組み込むときは、その演算の意味とメリットなど
ビット演算を導入した経緯や思想も書いてほしい・・・
ソース理解に時間がかかったり、修正が大変・・・
まあ、俺がお馬鹿なのかもしれないけど。
あと、763って751からの流れなんですか?
それとも別の流れ?
772:デフォルトの名無しさん
08/08/02 10:14:13
最後の2行から見ても明らかに
>まあ、俺がお馬鹿なのかもしれないけど。
が正解。
773:デフォルトの名無しさん
08/08/02 10:17:05
このスレって頭のいい奴もいるけど、
771みたいなバカもいる。
バカはROMっていろ!死ね771!!
774:それは俺か (w
08/08/02 10:59:13
まあ、バカにレスする奴はもっとバカだけどな。
775:デフォルトの名無しさん
08/08/02 11:02:09
1、2、4、8、16、32、64、128、256、512の完全最小ハッシュ値を作る。
URLリンク(www.ic-net.or.jp)
これか?
>>762は本当に頭がいい。>>763の書き込みがなかったら
意味も解らずスルーするところだった。
776:デフォルトの名無しさん
08/08/02 12:58:48
512の完全ハッシュを作ってそれを1~9のテーブルに掛けるって事?
分かった気がする。
777:デフォルトの名無しさん
08/08/02 13:59:12
>>775
でも、保守する奴が >>762 みたいに頭いいとは限らんから、
仕事のプログラムなら >>754-755 あたりのほうがいいと思う。
778:デフォルトの名無しさん
08/08/02 14:04:14
当たり前。こんなのは所詮パズル。商用コードでこんなの書けない。
>>762みたいなのが許されるのは趣味のプログラミングだけだよ。
779:デフォルトの名無しさん
08/08/02 16:19:14
後は極端に処理速度がネックになってるところとか、
ビックリするほど容量が無いプラットフォームとか、
コンパイラが準備されてなくてアセンブラで書かなきゃいけないような場合、
更にRISCみたいに見た目と実行順が違うような環境だと
読む量が少ない短いコードが逆に役に立つ。
自慢を理由に書くと間違いなく死を招く。
780:デフォルトの名無しさん
08/08/02 16:20:19
コメントで書いておけば十分じゃないかな。
今でもまだまだ、速度やサイズ重視の分野はあるし。だいぶ少なくはなっているけど。
781:デフォルトの名無しさん
08/08/02 16:32:12
現状、用途として大きそうなのはシェーダー周りか。
782:デフォルトの名無しさん
08/08/02 16:36:45
画像処理ならいくらでも速度欲しいけどな
783:デフォルトの名無しさん
08/08/02 16:49:03
昔、VUアセンブラの実装をしたが、ライブラリの増加により俺の約700byteのプログラムが
入らなくなり削りに削って「400byteだけ下さい!」と上司に嘆願したのは懐かしい思い出。
784:デフォルトの名無しさん
08/08/02 18:57:37
>>777
それは同意だけど、 >>762 のエッセンスを抜き出して、わかりやすくすれば
いいんじゃないかな
おそらく、2^a を掛けると aビット左シフトする、というのは誰にも自明だけど
1~9の値にマップするマジック定数がややトリッキーかと
なら、見た目にわかりやすいようシフト数を4倍にして、(ついでに右シフトにして)
こんな感じでどうだろうかね(64ビット整数が使えることが前提だけど^^)
/* assume that n is 2^a (1<=a<=9) */
return (0x9876543210LL / ( n * n * n * n )) & 0xf;
785:デフォルトの名無しさん
08/08/03 02:24:01
一番右の1を探すとき~a&(a-1)でできますよね、じゃあ一番左の1を探すときは何かありませんか?
786:デフォルトの名無しさん
08/08/03 02:37:33
掛け算が4回・割り算が1回ってのが、演算量的に・・・ 俺が8bitに慣れてるからかな?
64bit整数があるにしても、nが32bitならn*nで64bitでしょ。中間結果でbitが失われるんじゃ?
787:デフォルトの名無しさん
08/08/03 02:40:55
>>785 754とか755じゃダメなの?もっと速い/小さいのってこと?
788:デフォルトの名無しさん
08/08/03 02:55:56
>>785
関係ないがa&(-a)で右端の一ビットを得られるぞ、左端は無理じゃないか
789:デフォルトの名無しさん
08/08/03 03:17:47
URLリンク(www.nminoru.jp)
790:デフォルトの名無しさん
08/08/03 03:41:51
>>787-789
どうもです、今見た資料に左端を操作する命令列は存在しないって書いてあったorz
791:デフォルトの名無しさん
08/08/03 03:56:21
左右反転するビット演算子でもあればね
792:デフォルトの名無しさん
08/08/03 03:59:50
a = ( ( a >> 16 ) & 0x0000ffff ) | ( ( a << 16 ) & 0xffff0000 );
a = ( ( a >> 8 ) & 0x00ff00ff ) | ( ( a << 8 ) & 0xff00ff00 );
a = ( ( a >> 4 ) & 0x0f0f0f0f ) | ( ( a << 4 ) & 0xf0f0f0f0 );
a = ( ( a >> 2 ) & 0x33333333 ) | ( ( a << 2 ) & 0xCCCCCCCC );
a = ( ( a >> 1 ) & 0x55555555 ) | ( ( a << 1 ) & 0xAAAAAAAA );
793:784
08/08/03 17:00:12
>>786
もちろん変数n は64ビット長
LP64なら long型だと思ってもらえばいいです
演算量については、いまどきの投機実行するCPUなら
下手に条件判定入るよりは速いと思うけど、・・・まあ状況次第ですね
794:デフォルトの名無しさん
08/08/03 17:25:07
nが64bitでも、n*n*n*n の中間結果はbit失われるでそ。
795:デフォルトの名無しさん
08/08/03 18:31:31
でも、仕事に使うとなると、
「シンプルにしようや」
で終わってしまうんですよね~
そうすると、754や755に落ち着くのかな・・・
796:デフォルトの名無しさん
08/08/03 19:39:21
そりゃそうだよ。
よほど特段の理由が無い限り、シンプルが一番。
797:デフォルトの名無しさん
08/08/03 19:51:28
裸が一番いいのと一緒だ
798:デフォルトの名無しさん
08/08/03 21:10:39
>>794
2^9まででしょ?
799:デフォルトの名無しさん
08/08/03 21:12:54
は?
800:デフォルトの名無しさん
08/08/03 21:51:46
0x1 * 0x1 => 1
0x3 * 0x3 => 9
0x7 * 0x7 => 0x31
0xf * 0xf => 0xe1
0xff * 0xff => 0xfe01
0xfff * 0xfff => 0xffe001
0xffff * 0xffff => 0xfffe0001
0xfffff * 0xfffff => 0xffffe00001
これに規則性みたいなものを感じるんですが、
何か法則があるんでしょうか?
801:デフォルトの名無しさん
08/08/03 21:54:51
初めの3つはともかく、
9*9=81
99*99=9801
999*999=998001
と同じようなもんだろ
802:デフォルトの名無しさん
08/08/03 22:06:41
よくわからんが、ビット演算とかって、日本人よりも
インド人のほうが面白い発想しそうだね
803:デフォルトの名無しさん
08/08/03 22:09:36
>>800-801
2進数に考えれば、最初から綺麗に並ぶよ。
1 * 1 = 1
11 * 11 = 1001
111 * 111 = 11001
1111 * 1111 = 11100001
11111 * 1111 = 1111000001
804:デフォルトの名無しさん
08/08/03 22:16:49
0xffff * 0x10000 => 0xffff0000
0xffff0000 - 0xffff => 0xfffe0001
特に面白い事実はなさそうだが
805:デフォルトの名無しさん
08/08/03 22:21:59
99*99=9801
これが国民機ナンバーの正体かー
すると8801は?
93.8136 * 93.8136 = 8800.99
収束しないのか
806:デフォルトの名無しさん
08/08/03 22:22:36
収束?
807:デフォルトの名無しさん
08/08/03 22:25:25
ごめん適当言った
808:デフォルトの名無しさん
08/08/03 22:34:48
無理数ね。
809:デフォルトの名無しさん
08/08/03 23:10:51
λ... PC-8001, PC8201, PC-6001, &c. ...
810:デフォルトの名無しさん
08/08/03 23:48:03
獣の数字にまつわる屁理屈と同じようなもんだな
あえて8801に意味を見出すなら99*99-1100とかなんとか
811:デフォルトの名無しさん
08/08/03 23:49:53
9801-1100 = 8701だな
俺頭大丈夫k
812:デフォルトの名無しさん
08/08/04 00:08:26
PC9801が長いこと繁栄したのは99*99=9801
こういった力(ちから)を持つ数字が隠されていた影響に違いない。
その証拠に型番が9821に変わろうとしたとたん没落した。
きっと9801のままなら永遠の存在だったんだよ。
813:デフォルトの名無しさん
08/08/04 00:11:55
>>798 そうか、9bitのハッシュのエレガントな解法だったのね。ごめん。
ハッシュって、必要の都度、bit数見極めて作らなきゃいけないんだな・・・
814:デフォルトの名無しさん
08/08/04 01:24:27
実際に仕事でも使用可能な、
1.実用性がある
2.比較的わかりやすい
ビット演算のアルゴリズムって何だろうね・・・
815:デフォルトの名無しさん
08/08/04 01:50:11
名前がつくぐらい有名になればいいんじゃないかな。
例えばコメントに
// 762氏ハッシュ
とか書けるぐらいに。
816:デフォルトの名無しさん
08/08/04 01:56:23
すみません、
>"\1\2\3\010\6\4\011__\7\5"[n*0x5300000>>28];
の頭の"\1\2\3\010\6\4\011__\7\5"がいまいち良くわかりません。
817:デフォルトの名無しさん
08/08/04 02:06:28
ただの文字列リテラルだよ
818:デフォルトの名無しさん
08/08/04 02:06:59
コメントに、「ハッシュがどうの」なんて書く奴ばっかだからダメなんだよ。
コメントに絶対に書かなきゃいけないのは、>>751-752だよ。
どういう実装をしたかのコメントなんて二の次三の次。
それなのに仕様のコメントを怠ったままで「すげーテクニック使ってるんだぜ」的なコメントを残しても意味なし。
そんなものを残すぐらいなら、(最低限の>>751-752の他に)assertでも使った範囲チェック入れとけ。
もちろん、>>762のやり方に対するコメント(完全ハッシュ関数とテーブル)はあった方が良い。
けど、仕様についてのコメントの方がはるかに重要。
819:デフォルトの名無しさん
08/08/04 03:06:57
日本語でおk
820:デフォルトの名無しさん
08/08/04 03:45:03
日本人でおk
821:デフォルトの名無しさん
08/08/04 04:32:52
二本イレマスカ?
822:デフォルトの名無しさん
08/08/04 04:59:25
イマレス
823:デフォルトの名無しさん
08/08/04 08:02:17
#if 0 // オリジナルのロジック
...;
#else // 速度重視で書き換え
...;
#endif
824:デフォルトの名無しさん
08/08/04 08:15:04
"..."[...]という書き方をこの流れで始めて知った
何でこのスレにいるかって?
知るために見ているのさ
825:デフォルトの名無しさん
08/08/04 09:53:07
K&Rの頃のCをやってた人間からすれば常識
826:デフォルトの名無しさん
08/08/04 12:37:57
>>816 文字リテラル "abc"とかならキャラ型の配列だって判るでしょ。
スペース(0x20)より小さい値のcharは 「\8進数」 で書く約束になってる。
"\1\2\3・・・"は、char xxx[ ]={ 1, 2, 3, ・・・, 0 };という配列が生成される。
827:デフォルトの名無しさん
08/08/04 13:33:40
>>826
>スペース(0x20)より小さい値のcharは 「\8進数」 で書く約束になってる。
なってない。
828:デフォルトの名無しさん
08/08/04 17:24:05
\001 \002 \017 とかだよ。 Hexの場合は \xhh と書く約束になってる。
俺のはLSIC85とか adUc51とか、クミコ系ばっかりで、ANSIは知らないけど。
829:デフォルトの名無しさん
08/08/04 18:13:00
0x20以上の値で使ってはいけないという決まりもないわけで。
830:デフォルトの名無しさん
08/08/04 22:15:16
最下位8bitについてなら左右を逆転するコードあった筈
こんな感じだったと思うけど、よく覚えてないや
x:src y:dest
s=(x*0x02020202)&0x84422010
t=(x<<3)&0x420
y=(s+t)%1023
831:デフォルトの名無しさん
08/08/04 22:49:39
>>792で既出だべ。
832:デフォルトの名無しさん
08/08/04 23:59:20
>>828
\n \t \r とかもあるわけで。
833:デフォルトの名無しさん
08/08/05 00:45:34
>>832
は?
834:デフォルトの名無しさん
08/08/05 01:21:35
文字リテラルが配列の名前???
どうも「文字リテラル+[]」が良くわからん。
ビット演算うんぬんではなく・・・
C言語でこれを書いてコンパイルが通るのか?
どうもこのスレに付き合うには、大学などできちんと学ぶか
元々、この手のことが好きじゃないとついていけませんね・・・
社会人になってから、プログラムを覚えたアホアホな俺の
プリンみたいな脳みそでは、だめかorz
835:デフォルトの名無しさん
08/08/05 01:37:17
なんでワカラン??? 大学とか関係ないぞ。
char * buf = "01234567";
char a = buf[0];
が判れば、
char a = "01234567"[0];
だって判るだろ。
836:デフォルトの名無しさん
08/08/05 01:41:46
char a = 0["01234567"];
こんなのもある。これが直感的に納得しづらいというのはワカランでもないけど、
char a = "01234567"[0];
こっちは普通だべ。
837:デフォルトの名無しさん
08/08/05 09:00:56
>>834
>元々、この手のことが好きじゃないとついていけませんね・・・
当たり前だと思うんだが。
838:デフォルトの名無しさん
08/08/05 10:50:52
文字列定数がメモリ空間に配置されている状態をイメージできていないんだな。
プロセスメモリエディタかバイナリエディタと睨めっこでもしてみればいいんじゃね。
839:デフォルトの名無しさん
08/08/05 12:25:02
文字列リテラルは、コンパイラがDATAやTEXTのようなセグメントに配置して
プログラムの中に埋め込まれるちょっと特殊なchar[]にすぎん。
"hoge"とか書いた場合、これはそういう配列を暗黙にどっかに確保しろよと
コンパイラに言っているのと同時に、式の中で評価されるときは、その(無名の)
char配列の名前と同等に扱われる。
要はchar[]なのだから、char*な変数に文字列リテラルを代入したり
printf()のような関数に文字列リテラルを引数として渡したり、ということは
普通に・当然のようにやっているはずだ。
さすがにprintf("hello, world"); というコードを見たことが無いとは言わせない。
ならば、[]演算子を適用できるということも当然分かるはずだな。
多分、そういうコードを今まで見たことが無い、見慣れない、ってだけだろう。
840:デフォルトの名無しさん
08/08/05 12:32:50
>>834
[]を特殊なものだと思うからいけない。ただの演算子だ。
a[b]とあったら必ず*(a+b)と置き換えが可能だから、ただのポインタ演算とデリファレンスに成り下がるだろ。
デリファレンスするために、aかbのどちらかはポインタでもう一方は整数でないといけないだけだ。
例えばchar a = 0["01234567"]とあったらchar a = *(0 + "01234567")になり、即ちchar a = *("01234567")であり、char a = "01234567"[0]だ。
これでも理解しにくかったら、全部一時変数にしてしまえばいい。
const char * p = "01234567"; int i = 0; として、char a = p[i]; ならわかるだろ。。
841:デフォルトの名無しさん
08/08/05 13:15:16
おそらくは、
配列の名前[インデックス]
のように教えてる参考書の類が悪いんだろう。
842:デフォルトの名無しさん
08/08/05 15:15:59
>>834
このスレ開いただけでも望みはある!
843:デフォルトの名無しさん
08/08/05 18:04:55
すごいな。叩きが日常の2chで、シロートにここまで優しいのは、久しぶりに見た。
844:デフォルトの名無しさん
08/08/05 19:53:06
>>838
メモリをイメージする訓練も大切だが、
もっと抽象的に捉える訓練も忘れないで欲しいな。
845:デフォルトの名無しさん
08/08/05 20:05:18
そうだなー、最近そういうトレーニング怠ってるかも…俺。
846:デフォルトの名無しさん
08/08/05 21:13:44
>>841
真の文法を書いてる本は稀少なのかね。
847:デフォルトの名無しさん
08/08/05 21:27:48
>>846
真の文法を書いている本でも、いでおしんくらてっぃくなところは
はしょっているか、読み取れないようにしてるのが多いと思う。
実際、俺なんか、
int typedef integer;
なんて構文が許されるなどとはイソターネットで初めて知った。
848:デフォルトの名無しさん
08/08/05 21:44:04
なるほど、許されない理由がないから許されるんだな。
849:デフォルトの名無しさん
08/08/05 21:47:55
もしかして:void main(void)
850:デフォルトの名無しさん
08/08/05 22:11:34
>>846
真の文法をサポートする本とはLinuxのことである。
Linux以外は紛い物である。