【高速化】ビット演算 0x02
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん
2006/09/16(土) 09:46:26ビット演算
http://pc8.2ch.net/test/read.cgi/tech/1123918075/
関連スレ
アセンブラ… (゜□゜) ↑アッー!↓
http://pc8.2ch.net/test/read.cgi/tech/1148402614/
関連情報
Hacker's Delight
ttp://www.hackersdelight.org/
ハッカーのたのしみ―本物のプログラマはいかにして問題を解くか
ttp://www.amazon.co.jp/exec/obidos/ASIN/4434046683
ビットを数える・探すアルゴリズム
ttp://www.nminoru.jp/~nminoru/programming/bitcount.html
Bitboard
ttp://en.wikipedia.org/wiki/Bitboard
0002デフォルトの名無しさん
2006/09/16(土) 09:47:52_|___|_ 下がってろウジ虫共!
ヽ|・∀・|ノ 訓練教官のようかんマン先任軍曹が2getだ!
|__|
| |
>>1 貴様!俺のかんてんをどうするつもりだ!
>>3 あんこを入れる前と後に「サー」と言え!
>>4 ふざけるな!茶をだせ!茶っ葉落としたか!
>>5 貴様にはふやけたもなかをかき集めた値打ちしかない!
>>6 異人の手先の駄カステラめ!
>>7 まるでそびえ立つ葛だ!
>>8 栗を切り取って貴様の価値を絶ってやる!
>>9 お茶請けにもなれないゼリー風情が気取った事を言うな!
>>10-999 虎だ!虎になれ!虎屋のようかんを思い出せ!
>>1000 気に入った!家に来て俺を食っていいぞ!
0003デフォルトの名無しさん
2006/09/16(土) 09:48:26< | > 俺はグラットン持ちの通りすがりのナイトであって
|.|.| 3getしたがどうやってブロントって証拠だよ!!
|.|.|
|.|.|
< | > おいィ?お前それで良>>1のか?
...| | |. 仏の顔を>>2度までという名セリフを知らないのかよ
...| | |. 暗黒が持つと逆に頭がおかしくなって>>4ぬ
...| | |. グラットンす>>5いですね
.< .| .> >>6駄にaguるなネットポリスに捕まりたいのか?
/(.._..|..|..|.._..)ヽ それほどでも>>7い
>.─<>─.< このままでは俺の寿命がストレスでマッ>>8なんだが・・
ヾ ̄ヾ .√ ")' >>9枚で良い
.| .| 俺の怒りが有頂>>10になった
.| .|
.| .| おれパンチングマシンで>>100とか普通に出すし
) (
.▽
0004デフォルトの名無しさん
2006/09/16(土) 10:15:140005デフォルトの名無しさん
2006/09/16(土) 11:47:09必要なコピペを引き出したらあとは放置しましょう。
待機モード中の自動応答に本気でレスすると、無駄にログが流れ読みにくくなりますし
他の利用者の妨げになります。
0006デフォルトの名無しさん
2006/09/16(土) 17:48:57乙です
0007デフォルトの名無しさん
2006/09/16(土) 18:00:340008デフォルトの名無しさん
2006/09/18(月) 08:19:25〒 ! + 。 + 。 * 。
+ 。 | |
* + / / イヤッッホォォォオオォオウ!
∧_∧ / /
(´∀` / / + 。 + 。 * 。
,- f
/ ュヘ | * + 。 + 。 +
〈_} ) |
/ ! + 。 + + *
./ ,ヘ | このスレッドは1000を超えました。
ガタン ||| j / | | ||| 次スレも…BITクオリティ!!
―――――――――――― http://pc8.2ch.net/tech/
って1000取ろうとしたらすっかり忘れてた。
0009デフォルトの名無しさん
2006/09/18(月) 11:56:32こういう奴死んでくれないかな。
0010デフォルトの名無しさん
2006/09/19(火) 07:48:090011デフォルトの名無しさん
2006/09/21(木) 22:57:170012デフォルトの名無しさん
2006/09/22(金) 01:51:44取れてるじゃん。
0013デフォルトの名無しさん
2006/09/22(金) 23:28:21分岐を使わないのができた
uint64 wh = white & 0x7e7e7e7e7e7e7e7e; // 横移動のための番人
uint64 rev = 0;
uint64 e1, e2, e3, e4, e5, e6; // 空白から続く白石列
uint64 b1, b2, b3, b4, b5, b6; // 黒石から続く白石列
e1 = (mask0 <<1) & wh;
e2 = (e1 << 1) & wh;
e3 = (e2 << 1) & wh;
e4 = (e3 << 1) & wh;
e5 = (e4 << 1) & wh;
e6 = (e5 << 1) & wh;
b1 = (black >> 1) & wh;
b2 = (b1 >> 1) & wh;
b3 = (b2 >> 1) & wh;
b4 = (b3 >> 1) & wh;
b5 = (b4 >> 1) & wh;
b6 = (b5 >> 1) & wh;
rev |=
e1 & b1 |
e1 & b2 | e2 & b1 |
e1 & b3 | e2 & b2 | e3 & b1 |
e1 & b4 | e2 & b3 | e3 & b2 | e4 & b1 |
e1 & b5 | e2 & b4 | e3 & b3 | e4 & b2 | e5 & b1 |
e1 & b6 | e2 & b5 | e3 & b4 | e4 & b3 | e5 & b2 | e6 & b1;
0014デフォルトの名無しさん
2006/09/22(金) 23:29:29だけど、条件分岐を使って書いたコードよりかなり遅い
もっと高速化できないものか
0015・∀・)っ-○◎●新世紀ダンゴリオン ◆DanGorION6
2006/09/22(金) 23:46:53でもない限りありえない。
2項選択くらいならconditional move使えば簡単に表現できる。
x86ならレジスタ数が少ない上に32ビットレジスタ2本でようやく1つの64ビット値だから
それだとロード・ストアが頻発して全然速くない。
へたに1マス1ビットに割り振るよりは1バイトに振ったほうが小回りが利く分速くなることもある。
0016デフォルトの名無しさん
2006/09/22(金) 23:50:43rev |=e1 & (b1 | b2 | b3 | b4 | b5 | b6) |
e2 & (b1 | b2 | b3 | b4 | b5) |
e3 & (b1 | b2 | b3 | b4) |
e4 & (b1 | b2 | b3) |
e5 & (b1 | b2) |
e6 & b1;
とすれば、論理演算の回数を 42 から 26回に減る
さらに or の部分をまとめれば
rev |= e6 & b1;
rev |= e5 & (b1 |= b2);
rev |= e4 & (b1 |= b3);
rev |= e3 & (b1 |= b4);
rev |= e2 & (b1 |= b5);
rev |= e1 & (b1 | b6);
論理演算の回数は 17回
0017デフォルトの名無しさん
2006/09/23(土) 00:08:410018デフォルトの名無しさん
2006/09/23(土) 00:13:59AMD が出してたのがあるような気がするけどなんだっけ…
0019・∀・)っ-○◎●新世紀ダンゴリオン ◆DanGorION6
2006/09/23(土) 00:59:58つまり
src1 = func(src1, src2)
src1の値を保存したい場合は待避が必要になる。
レジスタ間移動
0020・∀・)っ-○◎●新世紀ダンゴリオン ◆DanGorION6
2006/09/23(土) 01:05:29レジスタ間移動だけでも整数の論理算術演算と同様にクロック数と
演算ユニットを使うし、ロード・ストアが絡むとさらに遅延が大きくなる。
x86でこの手の最適化をやる場合、テンポラリ変数をなるべく多用しない
(32ビットで同時に3〜4くらいに抑えるべき)のと、全部 &= や |= で
書いてみれば、吐き出される命令数が最低どのくらいになるかは
見当がつくと思う。
0021デフォルトの名無しさん
2006/09/23(土) 07:59:35uint64 wd = white & 0x007e7e7e7e7e7e00;//斜め移動のための番人
uint64 rev = 0;
uint64 e1, e2, e3, e4, e5, e6;//空白から続く白石列
uint64 b1;//黒石から続く白石列
e1 = (m << 9) & wd;
e2 = (e1 << 9) & wd;
e3 = (e2 << 9) & wd;
e4 = (e3 << 9) & wd;
e5 = (e4 << 9) & wd;
e6 = (e5 << 9) & wd;
rev |= e6 & (b1 = (black >> 9) & wd);
rev |= e5 & (b1 |= (b1 >> 9) & wd);
rev |= e4 & (b1 |= (b1 >> 9) & wd);
rev |= e3 & (b1 |= (b1 >> 9) & wd);
rev |= e2 & (b1 |= (b1 >> 9) & wd);
rev |= e1 & (b1 | (b1 >> 9) & wd);
0022デフォルトの名無しさん
2006/09/23(土) 08:01:25e6 = (m << 6*6) & wd;
とし、
rev |= e6 & (b1 = (black >> 9) & wd);
rev |= (e6>>=6) & (b1 |= (b1 >> 9) & wd);
としてもよさそうだが、一度にシフトすると番人を飛び越してしまうのでよろしくない
0023デフォルトの名無しさん
2006/09/27(水) 04:29:000024デフォルトの名無しさん
2006/09/27(水) 06:33:350025デフォルトの名無しさん
2006/09/27(水) 09:22:570026デフォルトの名無しさん
2006/09/27(水) 13:18:530027デフォルトの名無しさん
2006/09/27(水) 19:57:00ニーモニック丸暗記して作ったプログラムに独自のチェックサムモドキつけたりして
紙に書いてセーブしてワクワクしてただろ。
大人はそんな無駄でアホな事まずやらねぇ
0028デフォルトの名無しさん
2006/09/27(水) 22:52:33A1, B1, ... H1 などの横一列の状態を一意の数字(インデックス)に変換し、
あらかじめ作成しておいたテーブルを引きたい
マスの状態は白黒空の3種類なので、空:0,黒:1,白2として 3倍しながら値を足していけば
インデックスを計算できる。
#define isB(p) ((black&p)!=0)
#define isW(p) ((white&p)!=0)
#define V(p) (isB(p) ? 1 : isW(p) ? 2 : 0)
#define INDEX8(p1, p2, p3, p4, p5, p6, p7, p8)\
(((((((V(p1)*3+V(p2))*3+V(p3))*3+V(p4))*3+V(p5))*3+V(p6))*3+V(p7))*3+V(p8))
INDEX8(A1, B1, C1, D1, E1, F1, G1, H1);
この処理をビット演算を使って、華麗に高速に行う方法はないのでしょうか?
0029デフォルトの名無しさん
2006/09/28(木) 07:42:57分割統治法が使えそうだ
t = x & 0xcccc; x = (x & 0x3333) + (t >>= 1); x += t >>2;
t = x & 0xf0f0; x = (x & 0x0f0f) + (t >>= 3); x += t >> 4;
t = x & 0xff00; x = (x & 0x00ff) + (t >>= 7); x += t >> 8;
論理演算 6回、シフト 6回、加算 6回
3倍して足していく方法は、乗算 7回、加算7回 なので、少し速そう
0030デフォルトの名無しさん
2006/09/28(木) 08:12:34t = x & 0xf0f0f0f0; x = (x & 0x0f0f0f0f) + (t >>= 3); x += t >> 4;
t = x & 0xff00ff00; x = (x & 0x00ff00ff) + (t >>= 7); x += t >> 8;
ix1 = x >> 16;
ix2 = x & 0xffff;
とすれば、2行分のインデックスを同時にもとめることができる。
64ビット変数を使えば4行分をまとめて計算できる。
それならかなり高速になりそう
しかし、ビットボードは白黒別々なので、それを2ビットごとにまとめなくてはいけない
その処理に時間がかかりそうだ
0031デフォルトの名無しさん
2006/09/28(木) 08:34:46下位32ビットについて、
b = black & 0xffffffff;
b = ((b & 0xffff0000) << 16) | (b & 0xffff);
b = ((b & 0xff00ff00ff00) << 8) | (b & 0xff00ff00ff);
b = ((b << 4) | b) & 0x0f0f0f0f0f0f0f0f;
b = ((b << 2) | b) & 0x3333333333333333;
b = ((b << 1) | b) & 0x5555555555555555;
で間に0を入れ、白も同様に処理し、
x = b | (w << 1);
とすれば、2ビットごとにまとめることができる。
あとは >>30 の処理を行えば、下4行分のインデックスが求まる。
0032デフォルトの名無しさん
2006/10/06(金) 12:00:35間違ってない?
0033デフォルトの名無しさん
2006/10/06(金) 13:43:550034デフォルトの名無しさん
2006/10/06(金) 22:17:360035デフォルトの名無しさん
2006/10/08(日) 11:28:06回路図や真理値表は以下のページにあるぞ。
http://ja.wikipedia.org/wiki/%E5%8A%A0%E7%AE%97%E5%99%A8
いわゆるCPUだとかマイクロ・プロセッサつーのは、
その奥深くに 加算器に演算レジスタがあって、
ノイマン型にプログラム通りに計算をするためのものなんだから。
減算 や 負の数を扱うには「2の補数」
http://ja.wikipedia.org/wiki/2%E3%81%AE%E8%A3%9C%E6%95%B0
と言った捉え方で数を扱うのだ。
0036デフォルトの名無しさん
2006/10/08(日) 11:38:500037デフォルトの名無しさん
2006/10/10(火) 23:41:360038デフォルトの名無しさん
2006/10/10(火) 23:46:160039デフォルトの名無しさん
2006/10/10(火) 23:49:480040デフォルトの名無しさん
2006/10/10(火) 23:51:570041デフォルトの名無しさん
2006/10/10(火) 23:57:280042デフォルトの名無しさん
2006/10/10(火) 23:58:380043デフォルトの名無しさん
2006/10/11(水) 00:21:230044デフォルトの名無しさん
2006/10/11(水) 01:00:100045デフォルトの名無しさん
2006/10/11(水) 01:01:300046デフォルトの名無しさん
2006/10/11(水) 02:06:140047デフォルトの名無しさん
2006/10/11(水) 06:57:090048デフォルトの名無しさん
2006/10/11(水) 13:16:09http://aggregate.org/MAGIC/
0049デフォルトの名無しさん
2006/10/11(水) 16:56:33ひょっとしてradiumあたりで見た輩か?
>>1のサイトでとりあげられてる。
せめて>>1のサイトくらいみればよいのに・・・
0050デフォルトの名無しさん
2006/10/11(水) 23:15:53性能改善要求出る前にビット演算使うと白い目で見られる。
0051デフォルトの名無しさん
2006/10/11(水) 23:18:57例え処理が1行だけであっても、関数(インラインで良い)にしとけば文句でないはず。
0052デフォルトの名無しさん
2006/10/11(水) 23:26:39勿論明瞭なコメント付きでな。
0053デフォルトの名無しさん
2006/10/11(水) 23:36:36ついでに代替コードを書いておくとなお良い。
0054デフォルトの名無しさん
2006/10/13(金) 04:27:350055デフォルトの名無しさん
2006/10/13(金) 05:31:510056デフォルトの名無しさん
2006/10/13(金) 09:38:47確かにそれで文句が出ないどころかメンテしやすければ褒められるべきところではあるが
多少の遊び心があってもそれはそれで許される。
>>51-53のようなことをしてあれば。
(代替コードのテストも必要なことは当然なので、プログラマの負担はアップするが)
0057デフォルトの名無しさん
2006/10/13(金) 13:48:49パフォーマンス的に代替が効かないからこそ
そういうコードを書くわけだから
同等以上の速度が出た上に読みやすいコードを出せなければ
批難する事はできない。
もちろん意味もなくビット演算するアホの話は別として。
0058デフォルトの名無しさん
2006/10/13(金) 16:28:36上で出てるようなCでなんて書かないよ。
0059デフォルトの名無しさん
2006/10/13(金) 16:34:33なんか考えたくないからC言語で書くけどね。
まぁ、どうしてもビット回転(rotate)が必要ならインラインアセンブラの
使用も検討するが。
0060デフォルトの名無しさん
2006/10/13(金) 16:41:080061デフォルトの名無しさん
2006/10/13(金) 18:52:45いや、当たり前の事実を主張されてもなぁ。
しかもなぜにこのタイミングで?わけわからん。
0062デフォルトの名無しさん
2006/10/13(金) 21:02:46何が違うの?
0063デフォルトの名無しさん
2006/10/13(金) 21:26:250064デフォルトの名無しさん
2006/10/13(金) 23:34:07寧ろインラインアセンブラだとCコード部とのI/Fが簡単に書けるメリットはあるね。
0065デフォルトの名無しさん
2006/10/14(土) 00:47:40C言語との連携は関数呼び出しの形でのみによって実現される。
殆どのメモリアクセスはシンボルではなくオフセット値での指定となるからめんどい。
最適化の善し悪しはすべて自分の腕にかかっている。
インラインアセンブラ
Cのソースに埋め込むことが出来るので、必要な箇所を個別に関数化する必要がない。
関数内の局所変数にシンボリックにアクセスできる。
一部のコンパイラはインラインアセンブラで書いた箇所も勝手に最適化してくれやがる。
0066デフォルトの名無しさん
2006/10/14(土) 00:56:320067デフォルトの名無しさん
2006/10/17(火) 13:52:46どうして「プロセッサのスケジューリング管理」なんて話が出てくるのか誰か教えて!
0068デフォルトの名無しさん
2006/10/17(火) 16:26:530069デフォルトの名無しさん
2006/10/17(火) 17:04:370070デフォルトの名無しさん
2006/10/17(火) 17:27:16パイプラインでな、処理を円滑に進めるためには、命令の実行順序を適切に
並び替える必要があるんだ。命令実行順序の決定をスケジューリングという。
命令実行スケジューリングはふつうコンパイラが最適化の一環として施すが
インラインアセンブラで記述した部分はそのままの順序で出力されて最適化
されないことが多い。
0071デフォルトの名無しさん
2006/10/26(木) 23:04:230072デフォルトの名無しさん
2006/10/30(月) 22:09:370073デフォルトの名無しさん
2006/10/30(月) 22:39:25>ハッカーのたのしみ
は、アマゾンで評価が高いみたいですが
本当に読んで面白い本なんですか?
0074デフォルトの名無しさん
2006/10/30(月) 22:47:16それはお前がビット演算を楽しめるかどうかによる。
0075デフォルトの名無しさん
2006/10/31(火) 03:09:00もしもあなたが書き溜めたソースコードを持っているのなら…
0076デフォルトの名無しさん
2006/11/15(水) 19:13:21条件分岐をしないで絶対値を求めたいのですが…
0077デフォルトの名無しさん
2006/11/15(水) 20:26:02このへん見てみたら?
http://www.thescripts.com/forum/thread212935.html
0078デフォルトの名無しさん
2006/11/15(水) 21:53:55return (x^y)-y;
か。
今ならcmovのほうが速いだろうけど
0079デフォルトの名無しさん
2006/11/15(水) 22:56:58とりあえずリンク先を参考に試してみようと思います
ありがとうございました
0080デフォルトの名無しさん
2006/11/26(日) 15:29:110081デフォルトの名無しさん
2006/12/02(土) 22:52:420082デフォルトの名無しさん
2006/12/03(日) 07:55:42根本的に排除する方法ってないんですか?
こういう場合はできるよってのがあったらそれも知りたいです。
もうビット演算のこと以外考えたくないんです。
0083デフォルトの名無しさん
2006/12/03(日) 08:40:06論理回路にif演算器はない。
0084デフォルトの名無しさん
2006/12/03(日) 08:40:31x;
} else {
y;
}
⇒
switch(a){
default:
x;
break;
case 0:
y;
}
0085デフォルトの名無しさん
2006/12/03(日) 08:50:26一生、縁が切れないんですか??
もう勘弁しいてほしいんです。
ソース読みにくいのってみんなif文の所為じゃないですか。
この絶望のまま生きていたくない。
並列計算がうまくいかないのだってきっと条件分岐のせいですよ。
諸悪の根源と思っていますよ、もう。
ところで、論理シフトとかってあれは論理演算が関係してるんですか?
0086デフォルトの名無しさん
2006/12/03(日) 09:38:32x=c;
} else {
x=d;
}
x=(a>b)*c;
x+=!(a>b)*d;
こんな感じかな?
ビット演算じゃ無いけど
0087デフォルトの名無しさん
2006/12/03(日) 10:20:41x;
} else {
y;
}
⇒
n_if(a){
x && a || y && !a;
}
0088デフォルトの名無しさん
2006/12/04(月) 17:34:01void f();
void g();
int hoge;
before:
if (hoge != 0)
f();
else
g();
after:
typedef (*func_t)();
func_t table[] = {f, g};
table[hoge != 0]();
0089・∀・)っ-○◎●新世紀ダンゴリオン ◆DanGorION6
2006/12/04(月) 22:59:51d = a ? b : c;
とかでも使えば?組み込みのCMOV命令に展開してくれたりするし
SIMD系の命令セットは比較命令はマスク生成のことが多い
0090デフォルトの名無しさん
2006/12/04(月) 23:03:57命令20ぐらいをズラスラ書いたのより、テーブル参照1つの方が遅かったりする。
0091デフォルトの名無しさん
2006/12/07(木) 00:04:36switchで振り分けた方が遥かに速かったわ。恐るべし分岐予測。
0092・∀・)っ-○◎●新世紀ダンゴリオン ◆DanGorION6
2006/12/07(木) 00:39:10009382
2006/12/11(月) 04:57:32if文なしのジャンプなしで何とかならないでしょうか??
0094デフォルトの名無しさん
2006/12/11(月) 18:38:360095デフォルトの名無しさん
2006/12/18(月) 22:14:180096デフォルトの名無しさん
2006/12/25(月) 20:04:45adc pc, a
0097デフォルトの名無しさん
2006/12/30(土) 23:15:580098 【大吉】
2007/01/01(月) 00:23:580099デフォルトの名無しさん
2007/01/01(月) 13:31:160100デフォルトの名無しさん
2007/01/03(水) 13:42:060101デフォルトの名無しさん
2007/01/03(水) 19:31:35>根本的に排除する方法ってないんですか?
>こういう場合はできるよってのがあったらそれも知りたいです。
ビット演算以外の仕事は「引き受けない」
0102デフォルトの名無しさん
2007/01/03(水) 23:21:49まずプロセッサから設計した方がいいんじゃないか
0103デフォルトの名無しさん
2007/01/04(木) 00:46:05cmp+jeの組み合わせがいやならsub+jneでどうだろうか。
0104デフォルトの名無しさん
2007/01/06(土) 15:01:25int i;として
iが0以外なら1を、iが0なら0を返すビット演算は
i!=0以上にコンパクトにできるのでしょうか?
n = i!=0;と括弧つけてもやや読みづらいので。
(bool)iならば可読的なので喜んで使いたいのですが、Cなので残念ながら…
0105デフォルトの名無しさん
2007/01/06(土) 15:03:57なんてどう?
0106デフォルトの名無しさん
2007/01/06(土) 21:00:27(bool)i
0107デフォルトの名無しさん
2007/01/06(土) 22:58:090108・∀・)っ-○◎●新世紀ダンゴリオン ◆DanGorION6
2007/01/06(土) 23:02:40#define TO_BOOL(x) ((x) != 0)
0109デフォルトの名無しさん
2007/01/06(土) 23:04:450110デフォルトの名無しさん
2007/01/06(土) 23:07:38C、C++の最適化について語るスレ
http://pc10.2ch.net/test/read.cgi/tech/1084676298/
団子ちゃん、↑こっちのスレの結果はどうなったの?
やっぱり、団子ちゃんが適当なこと吹いてただけなの?
0111デフォルトの名無しさん
2007/01/07(日) 07:00:180/!0で充分だから
0112デフォルトの名無しさん
2007/01/07(日) 22:11:550113デフォルトの名無しさん
2007/01/14(日) 00:16:55これでビット演算だお^ω^
0114デフォルトの名無しさん
2007/01/18(木) 00:08:57加算器ってこんな感じじゃない?(ちょっと冗長かも)
int ADD(int x, int y, int c) {
return (x | y | c) ?
(((x & 1) ^ (y & 1) ^ (c & 1))
| (ADD(x >> 1, y >> 1,
(( !(x & 1) & (y & 1) & (c & 1))
| ( (x & 1) & !(y & 1) & (c & 1))
| ( (x & 1) & (y & 1) & !(c & 1))
| ( (x & 1) & (y & 1) & (c & 1)))) << 1)) : 0;
}
誰か減算器↓
0115デフォルトの名無しさん
2007/01/18(木) 00:48:41int ADD(int x,int y,int c){return ADD_((x&y)<<1|c,x^y);}
int SUB(int x,int y,int c){return ADD(x,~y,c^1);}
0116デフォルトの名無しさん
2007/01/18(木) 16:58:05! がオーバーロードされてたら、二回も呼ばれることになるぜ。
0117デフォルトの名無しさん
2007/01/19(金) 01:20:26十分ありえるけどな。
0118デフォルトの名無しさん
2007/01/19(金) 14:36:230119デフォルトの名無しさん
2007/01/19(金) 18:41:42ビットを数えるってのがよくあるpop関数のことなら死ぬほど既出。
0120デフォルトの名無しさん
2007/01/23(火) 07:38:250121デフォルトの名無しさん
2007/01/23(火) 10:19:53http://pc10.2ch.net/test/read.cgi/tech/1169104637/l50
0122デフォルトの名無しさん
2007/01/26(金) 23:52:21こいつのせいでビット操作のスレになってるじゃないか
0123デフォルトの名無しさん
2007/01/29(月) 12:22:020124デフォルトの名無しさん
2007/02/12(月) 18:20:58ttp://graphics.stanford.edu/~seander/bithacks.html
こんなサイトが(英語だけど)
テンプレに入れる?
0125デフォルトの名無しさん
2007/02/12(月) 21:33:100126デフォルトの名無しさん
2007/02/12(月) 22:46:320127デフォルトの名無しさん
2007/02/13(火) 07:43:070128デフォルトの名無しさん
2007/02/13(火) 23:14:23煽りぬきで
0129デフォルトの名無しさん
2007/02/13(火) 23:51:38さすがに、ネタ切れにて閉店でいいと思うよ。
0130デフォルトの名無しさん
2007/02/15(木) 15:02:080131デフォルトの名無しさん
2007/02/15(木) 15:47:08で、この i からそれぞれ 2007, 2, 15 って数字が欲しいんだけど
誰かカッコ良くビット演算使ってやってください。
0132デフォルトの名無しさん
2007/02/15(木) 15:50:34実質的には除数固定で割り算を行うのと同じだから
割り算の話になるな。
0133デフォルトの名無しさん
2007/02/15(木) 16:48:060134デフォルトの名無しさん
2007/02/15(木) 16:53:01それすごくもったいなくないか
たしか
日:1-31 (5bit)
月:1-12 (4bit)
年:00-99 (7bit)
で 16bit っつー表記があったな
FDとかHDのタイムスタンプとか
今なら年だけ
0000-9999 (14bit)
でも 23bit で余裕な訳だが
0135デフォルトの名無しさん
2007/02/15(木) 17:03:23そんなところでビットをケチったってしょうがねぇべさ。
そのフォーマット(MS-DOSのFATだな)はタイムスタンプが2秒単位でしか記録できないしね。
#hour:5, minute:6, second:5
0136デフォルトの名無しさん
2007/02/16(金) 03:33:4710進数を3進数に変換するコードはJAVAでどう書きますか?
0137デフォルトの名無しさん
2007/02/16(金) 03:46:470138デフォルトの名無しさん
2007/02/16(金) 14:24:000139デフォルトの名無しさん
2007/02/16(金) 15:18:45大抵は無意味だけど
オナニーとしてはナカナカそそる
0140デフォルトの名無しさん
2007/02/16(金) 15:28:210141デフォルトの名無しさん
2007/02/16(金) 15:35:590142デフォルトの名無しさん
2007/02/16(金) 15:55:533| 5 2
1
10進数:17 -> 3進数:122
10進数から3進数への変換て、これであってる?
0143デフォルトの名無しさん
2007/02/16(金) 15:59:57extern boost::mt19937 brand;
inline const float&n_rand(){
static float x;
*((unsigned int*)&x)=(brand()&0x7FFFFF)|0x3F000000;
return x;
}
とかやってる俺はkusobaka
0144デフォルトの名無しさん
2007/02/16(金) 20:57:54staticいらないだろ。
0145デフォルトの名無しさん
2007/02/16(金) 23:56:47演算子があれば良いんだけどな。
STLやboostを使っても型変換が必要だし。
0146デフォルトの名無しさん
2007/02/16(金) 23:58:080147デフォルトの名無しさん
2007/02/17(土) 00:00:30ところで、乱数の範囲はそれでいいのか?
2進表現で0x3f800000 から 0x3fffffff にして、そこから 1.0f を引くと [0..1) になって使いやすいと思うが。
0148デフォルトの名無しさん
2007/02/17(土) 01:31:320149デフォルトの名無しさん
2007/02/17(土) 01:54:260150デフォルトの名無しさん
2007/02/17(土) 08:36:230151デフォルトの名無しさん
2007/02/18(日) 21:02:060152150
2007/02/18(日) 21:13:28これでOKだ。
x = ( ( x >> 8 ) & 0x00ff00ff ) | ( ( x << 8 ) & 0xff00ff00 );
x = ( ( x >> 16 ) & 0x0000ffff ) | ( ( x << 16 ) & 0xffff0000 );
0153デフォルトの名無しさん
2007/02/19(月) 09:11:59x = (x & 0x000000ff) << 24 | (x & 0x0000ff00) << 8
| (x & 0x00ff0000) >> 8 | (x & 0xff000000) >> 24;
と書いては何かまずいの?
152の方法だと1行目で算出したxを2行目で使っているので
1行目の処理と2行目の処理の並列性が無いし、マスク用の
定数が4バイトの2つ、3バイトの1つ、2バイトの1つで、
どのCPUを想定しているのかは知らないけど、普通は
上の方法のマスク定数より長いコードになるのでは。
24回のshiftが16回のshiftより時間がかかる状況なら
上の方法は好ましくないし、エンディアン変換のビット長が
64bitなら152の方法のほうが良いように思うが。
0154デフォルトの名無しさん
2007/02/19(月) 18:34:240155デフォルトの名無しさん
2007/02/19(月) 21:49:23ttp://msdn2.microsoft.com/ja-jp/library/a3140177(VS.80).aspx
0156デフォルトの名無しさん
2007/02/20(火) 21:52:40?
0157デフォルトの名無しさん
2007/03/01(木) 22:52:200158デフォルトの名無しさん
2007/03/21(水) 06:17:18連続した場合ね。
0159デフォルトの名無しさん
2007/03/22(木) 00:34:100160デフォルトの名無しさん
2007/03/22(木) 08:22:3530年前の8bit時代から頭の中進歩してないオジサマ丸出しだねw
しかも昔の8bitマイコンだって命令サイクルと実クロックは別物だしね
0161デフォルトの名無しさん
2007/03/22(木) 21:47:22知ったか厨の典型だな。(w
0162デフォルトの名無しさん
2007/04/07(土) 02:22:120163デフォルトの名無しさん
2007/04/29(日) 08:20:140164デフォルトの名無しさん
2007/04/29(日) 10:38:150165デフォルトの名無しさん
2007/04/29(日) 10:44:470166デフォルトの名無しさん
2007/04/29(日) 10:52:160167デフォルトの名無しさん
2007/04/29(日) 12:29:580168デフォルトの名無しさん
2007/04/29(日) 18:46:240169デフォルトの名無しさん
2007/04/30(月) 02:15:380170デフォルトの名無しさん
2007/04/30(月) 07:39:020171デフォルトの名無しさん
2007/05/03(木) 20:17:24>if(hoge & 0x000000C0)
>みたいな書き方出来ると思うのですが
>両方のbitが立ってることを確認したければ
>if(hoge & 0x000000C0 == 0x000000C0)
>って書くしか方法ないですか?
以下から正しいものを選べ
1) if(hoge & 0x000000C0 & 0x000000C0)
2) if((hoge & 0x000000C0) & 0x000000C0)
3) if(!((hoge & 0x000000C0) ^ 0x000000C0))
4) if((hoge & 0x00000080) && (hoge & 0x00000040))
5) if(~(hoge | ~0x000000C0))
6) if(~(~hoge | ~0x000000C0))
0172デフォルトの名無しさん
2007/05/03(木) 20:20:410173デフォルトの名無しさん
2007/05/03(木) 20:30:47#define MASK 0x0000C0C0
int bittesta(int hoge)
{
if((hoge & MASK) == MASK){
return 1;
}else{
return 0;
}
}
int bittestb(int hoge)
{
if(!((hoge & MASK) ^ MASK)){
return 1;
}else{
return 0;
}
}
int main(int ac, char **av)
{
int hoge = 1234;
bittesta(hoge);
bittestb(hoge);
return 0;
}
0174デフォルトの名無しさん
2007/05/03(木) 20:31:55pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
andl $49344, %eax
cmpl $49344, %eax
jne L10
movl $1, -4(%ebp)
jmp L9
L10:
movl $0, -4(%ebp)
L9:
movl -4(%ebp), %eax
leave
ret
_bittestb:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
andl $49344, %eax
cmpl $49344, %eax
jne L13
movl $1, -4(%ebp)
jmp L12
L13:
movl $0, -4(%ebp)
L12:
movl -4(%ebp), %eax
leave
ret
0175デフォルトの名無しさん
2007/05/03(木) 20:34:17いまどきのコンパイラは
>>171 (3) で書いても
最適化されて >>172 になってるんだね
0176デフォルトの名無しさん
2007/05/03(木) 22:06:56例えば1か0が格納される変数(Aと仮定)のスイッチ切り替えの場合
【例�@】
if(A == 1)
{
A = 0;
}
else
{
A = 1;
}
【例�A】
A = A ^ (0 + 1);
この場合早いのはやはり例�Aなのでしょうか?
0177デフォルトの名無しさん
2007/05/03(木) 22:13:48が速い。まあ、例2と同じだあな。
0178デフォルトの名無しさん
2007/05/03(木) 22:18:35有難うございました。
0179デフォルトの名無しさん
2007/05/03(木) 22:24:42A = 1-A
のが速かったりするぞ
0180デフォルトの名無しさん
2007/05/04(金) 00:48:43いや、今回は1と0で設定されてるけどほんとは3と5かもしれないだろ
そういう場合ってやっぱA ^= 1;とかA = 1-Aより
A ^= (3 + 5);のほうが正解なんじゃないか?
1と0ならA = 1-Aとかでもいいんだけどな
0181・∀・)っ-○◎●
2007/05/04(金) 00:52:14A ^= 8;
????????????????????????????
Aには1か0が格納されるって最初の条件で確定してるんだが
0183・∀・)っ-○◎●
2007/05/04(金) 00:55:140184180
2007/05/04(金) 00:55:36A ^= 1;でいいと思うが
A変数に3か5が入ってる設定だと
A ^= 5;じゃダメだろ?
だったらどちらにでも応用できる
A ^= (1 + 0);
A ^= (5 + 3);
がいいんじゃないかって話をしたかっただけだ。
0185・∀・)っ-○◎●
2007/05/04(金) 00:56:410186180
2007/05/04(金) 00:59:140187・∀・)っ-○◎●
2007/05/04(金) 00:59:43A = ~A;
0188デフォルトの名無しさん
2007/05/04(金) 01:01:020189180
2007/05/04(金) 01:01:45確かに8じゃ無理だったwwwwwwwww
0190・∀・)っ-○◎●
2007/05/04(金) 01:24:45仮に全ビット使う場合の話。
信号制御用の1ビットレジスタをこれで操作してたような。
0か1かならこっちのほうが素直か
A = !A;
0191デフォルトの名無しさん
2007/05/04(金) 01:59:07要するに A ^= (3 ^ 5);
0192デフォルトの名無しさん
2007/05/04(金) 08:32:250193デフォルトの名無しさん
2007/05/04(金) 08:50:20どう書くと一番短いですか?
0194デフォルトの名無しさん
2007/05/04(金) 08:52:030195デフォルトの名無しさん
2007/05/04(金) 08:59:54{
if ((w && 0x0010) != 0x0010)
{
b = TRUE;
}
else
{
b = FALSE;
}
}
0196デフォルトの名無しさん
2007/05/04(金) 09:05:23ありがとん
0197デフォルトの名無しさん
2007/05/04(金) 09:17:53a:= (a+ (a shr 2) ) and 3;
これだと 1,2,3の循環になるな
0198デフォルトの名無しさん
2007/05/04(金) 12:09:440199デフォルトの名無しさん
2007/05/04(金) 12:19:481000
0000
0001
0011
0010
0110
0100
0101
0111
0200デフォルトの名無しさん
2007/05/04(金) 12:21:58,. -ヤ'''カー、 /Y⌒Y⌒Y⌒Y⌒Yヾ
ー―ァ /r⌒|:::|⌒ヾ
_ノ オ{( |0| )} オオオォォォォ!!!!!
__,ヽ,ヾ,_|V|,_ノ、/ ,r-,,=
,゛==ゝ_ViV_ノ~i/ 〃 `ー―-、
/ /⌒`//´⌒c/^^^ ))))))))))
,,―イ {ー''"~{ {~゛`ー`/'`'~/ー--―'
)) ,./ゝ_/∧ゝ_ノ ノ
ー''" |ロ ロ |
人,_,人,_,人,_,人,_,人,_,
<適当な番号をゲット!!>
0201デフォルトの名無しさん
2007/05/04(金) 15:08:210202デフォルトの名無しさん
2007/05/04(金) 16:12:030203デフォルトの名無しさん
2007/05/04(金) 16:43:420204デフォルトの名無しさん
2007/05/04(金) 16:47:100205デフォルトの名無しさん
2007/05/04(金) 16:50:330206デフォルトの名無しさん
2007/05/05(土) 02:12:41if(v){ ..... }
vのビット列が [10000000] と [00000001]
ではやっぱり前者の方が早いんだろうか
0207デフォルトの名無しさん
2007/05/05(土) 02:21:080208デフォルトの名無しさん
2007/05/05(土) 02:37:550209デフォルトの名無しさん
2007/05/05(土) 03:18:030210デフォルトの名無しさん
2007/05/05(土) 03:39:360211デフォルトの名無しさん
2007/05/05(土) 11:01:090212デフォルトの名無しさん
2007/05/05(土) 11:21:150213デフォルトの名無しさん
2007/05/05(土) 12:16:520214デフォルトの名無しさん
2007/05/06(日) 17:55:550215デフォルトの名無しさん
2007/05/14(月) 21:23:54float[] p = {
0.000f, 0.000f, 1.000f, 5.373f, 0.000f, 0.998f, 4.989f, 0.000f, 1.075f, 5.000f, 0.000f, 0.000f,
0.000f, 5.373f, 0.998f, 4.865f, 4.865f, 0.951f, 4.970f, 2.370f, 1.160f, 5.000f, 1.326f, 0.000f,
0.000f, 4.989f, 1.075f, 2.370f, 4.970f, 1.160f, 3.700f, 3.700f, 0.179f, 4.473f, 2.598f, 0.000f,
0.000f, 5.000f, 0.000f, 1.326f, 5.000f, 0.000f, 2.598f, 4.473f, 0.000f, 3.536f, 3.536f, 0.000f,
};
float[] q = new float[384];
int i,j,k;
for(i=0;i<8;i++) {
k = (((i>>>2)^(i>>>1)^i)&1)*12;
for(j=0;j<16;j++) {
q[i*48+j*3+0] = ((i&1)==0)?p[(j^k)*3+0]:-p[(j^k)*3+0];
q[i*48+j*3+1] = ((i&2)==0)?p[(j^k)*3+1]:-p[(j^k)*3+1];
q[i*48+j*3+2] = ((i&4)==0)?p[(j^k)*3+2]:-p[(j^k)*3+2];
}}
for(i=0;i<32;i++) {
for(j=0;j<12;j++) { System.out.printf("%+6.3ff,",q[i*12+j]); }
System.out.print("\n");
}
0216215の出力結果(1/2)
2007/05/14(月) 21:26:12+0.000f,+5.373f,+0.998f,+4.865f,+4.865f,+0.951f,+4.970f,+2.370f,+1.160f,+5.000f,+1.326f,+0.000f,
+0.000f,+4.989f,+1.075f,+2.370f,+4.970f,+1.160f,+3.700f,+3.700f,+0.179f,+4.473f,+2.598f,+0.000f,
+0.000f,+5.000f,+0.000f,+1.326f,+5.000f,+0.000f,+2.598f,+4.473f,+0.000f,+3.536f,+3.536f,+0.000f,
-0.000f,+5.000f,+0.000f,-1.326f,+5.000f,+0.000f,-2.598f,+4.473f,+0.000f,-3.536f,+3.536f,+0.000f,
-0.000f,+4.989f,+1.075f,-2.370f,+4.970f,+1.160f,-3.700f,+3.700f,+0.179f,-4.473f,+2.598f,+0.000f,
-0.000f,+5.373f,+0.998f,-4.865f,+4.865f,+0.951f,-4.970f,+2.370f,+1.160f,-5.000f,+1.326f,+0.000f,
-0.000f,+0.000f,+1.000f,-5.373f,+0.000f,+0.998f,-4.989f,+0.000f,+1.075f,-5.000f,+0.000f,+0.000f,
+0.000f,-5.000f,+0.000f,+1.326f,-5.000f,+0.000f,+2.598f,-4.473f,+0.000f,+3.536f,-3.536f,+0.000f,
+0.000f,-4.989f,+1.075f,+2.370f,-4.970f,+1.160f,+3.700f,-3.700f,+0.179f,+4.473f,-2.598f,+0.000f,
+0.000f,-5.373f,+0.998f,+4.865f,-4.865f,+0.951f,+4.970f,-2.370f,+1.160f,+5.000f,-1.326f,+0.000f,
+0.000f,-0.000f,+1.000f,+5.373f,-0.000f,+0.998f,+4.989f,-0.000f,+1.075f,+5.000f,-0.000f,+0.000f,
-0.000f,-0.000f,+1.000f,-5.373f,-0.000f,+0.998f,-4.989f,-0.000f,+1.075f,-5.000f,-0.000f,+0.000f,
-0.000f,-5.373f,+0.998f,-4.865f,-4.865f,+0.951f,-4.970f,-2.370f,+1.160f,-5.000f,-1.326f,+0.000f,
-0.000f,-4.989f,+1.075f,-2.370f,-4.970f,+1.160f,-3.700f,-3.700f,+0.179f,-4.473f,-2.598f,+0.000f,
-0.000f,-5.000f,+0.000f,-1.326f,-5.000f,+0.000f,-2.598f,-4.473f,+0.000f,-3.536f,-3.536f,+0.000f,
0217215の出力結果(2/2)
2007/05/14(月) 21:27:16+0.000f,+4.989f,-1.075f,+2.370f,+4.970f,-1.160f,+3.700f,+3.700f,-0.179f,+4.473f,+2.598f,-0.000f,
+0.000f,+5.373f,-0.998f,+4.865f,+4.865f,-0.951f,+4.970f,+2.370f,-1.160f,+5.000f,+1.326f,-0.000f,
+0.000f,+0.000f,-1.000f,+5.373f,+0.000f,-0.998f,+4.989f,+0.000f,-1.075f,+5.000f,+0.000f,-0.000f,
-0.000f,+0.000f,-1.000f,-5.373f,+0.000f,-0.998f,-4.989f,+0.000f,-1.075f,-5.000f,+0.000f,-0.000f,
-0.000f,+5.373f,-0.998f,-4.865f,+4.865f,-0.951f,-4.970f,+2.370f,-1.160f,-5.000f,+1.326f,-0.000f,
-0.000f,+4.989f,-1.075f,-2.370f,+4.970f,-1.160f,-3.700f,+3.700f,-0.179f,-4.473f,+2.598f,-0.000f,
-0.000f,+5.000f,-0.000f,-1.326f,+5.000f,-0.000f,-2.598f,+4.473f,-0.000f,-3.536f,+3.536f,-0.000f,
+0.000f,-0.000f,-1.000f,+5.373f,-0.000f,-0.998f,+4.989f,-0.000f,-1.075f,+5.000f,-0.000f,-0.000f,
+0.000f,-5.373f,-0.998f,+4.865f,-4.865f,-0.951f,+4.970f,-2.370f,-1.160f,+5.000f,-1.326f,-0.000f,
+0.000f,-4.989f,-1.075f,+2.370f,-4.970f,-1.160f,+3.700f,-3.700f,-0.179f,+4.473f,-2.598f,-0.000f,
+0.000f,-5.000f,-0.000f,+1.326f,-5.000f,-0.000f,+2.598f,-4.473f,-0.000f,+3.536f,-3.536f,-0.000f,
-0.000f,-5.000f,-0.000f,-1.326f,-5.000f,-0.000f,-2.598f,-4.473f,-0.000f,-3.536f,-3.536f,-0.000f,
-0.000f,-4.989f,-1.075f,-2.370f,-4.970f,-1.160f,-3.700f,-3.700f,-0.179f,-4.473f,-2.598f,-0.000f,
-0.000f,-5.373f,-0.998f,-4.865f,-4.865f,-0.951f,-4.970f,-2.370f,-1.160f,-5.000f,-1.326f,-0.000f,
-0.000f,-0.000f,-1.000f,-5.373f,-0.000f,-0.998f,-4.989f,-0.000f,-1.075f,-5.000f,-0.000f,-0.000f,
0218デフォルトの名無しさん
2007/05/14(月) 21:53:430219デフォルトの名無しさん
2007/05/14(月) 23:11:470220デフォルトの名無しさん
2007/05/15(火) 00:22:46は
k = ((i>>>2)&4)*12;
と等価じゃない?
0221デフォルトの名無しさん
2007/05/15(火) 00:24:00は
k = ((i>>>2)&1)*12;
と等価
0222デフォルトの名無しさん
2007/05/15(火) 00:25:450223デフォルトの名無しさん
2007/05/15(火) 00:56:43オブジェクト指向すげえよ
0224デフォルトの名無しさん
2007/05/15(火) 02:01:14^は排他的論理和、>>>は符号無し右シフト、&は論理積なので、
k=(((i>>>2)^(i>>>1)^i)&1)*12はi=1,2,4,7の時にk=12、i=0,3,5,6の時にk=0となる。
全然等価じゃねーぞ。
0225215
2007/05/15(火) 03:58:02k = (((i>>>2)^(i>>>1)^i)&1)*12;
上の文は、iのパリティがevenであればk=0、oddであればk=12とする処理を行う部分ですが
iの値域が0〜7に限られるため、パリティの計算は下3bitに対してのみ行っています。
k = (Integer.bitCount(i)&1)*12; とする手もありますが、今回は先のように書きました。
p[0]〜p[15]を4x4の行列と見た場合に、q[]にその値をコピーする
for(j=0;j<16;j++) { q[j] = p[j^k]; }
の処理はkの値によって以下のような振る舞いの変化をします。
k=0:そのまま、k=3:列を逆順に入れ替え、k=12:行を逆順、k=15:行・列ともに逆順
0226デフォルトの名無しさん
2007/05/15(火) 04:07:12まあ、環境によるとは思うが。
0227デフォルトの名無しさん
2007/05/20(日) 08:13:370228デフォルトの名無しさん
2007/05/22(火) 07:41:36そのビットの位置(左右どちらからでもよい)を求めたいのですが
↓のNTZやNLZを求めるアルゴリズムを使うのよりも高速にできませんか?
http://www.nminoru.jp/~nminoru/programming/bitcount.html
立っているビットの数が一つという条件があるので
何か工夫できないか考えたんですけど思いつきません。
0229デフォルトの名無しさん
2007/05/22(火) 08:06:110230デフォルトの名無しさん
2007/05/22(火) 08:07:19何か参考になる方法ってありますか?
0231デフォルトの名無しさん
2007/05/22(火) 08:18:56memcpyより高速な手法が存在するとしたら、世の中のmemcpyはその高速
な手法を使うんじゃない?
0232デフォルトの名無しさん
2007/05/22(火) 08:24:56ビット単位で転送するという話でもない限り、スレ違い。
0233デフォルトの名無しさん
2007/05/22(火) 08:26:58いいえ。
0234デフォルトの名無しさん
2007/05/22(火) 08:31:370235デフォルトの名無しさん
2007/05/22(火) 08:35:42http://p2.chbox.jp/read.php?host=pc8.2ch.net&bbs=tech&key=1123918075&ls=all
ここの377に似たような質問があるね。
0236デフォルトの名無しさん
2007/05/22(火) 08:39:30ビット位置を持って回ることを検討したか?
>>230
つ [ゼロコピー]
0237デフォルトの名無しさん
2007/05/22(火) 09:05:14ビットはこんな風に複数のビットが立ってる変数から取り出してます。
UInt32 bits;
...
while(bits)
{
UInt32 bit = bits&(-bits);
UInt32 bit_position = get_bit_position(bit);
...
}
で、このget_bit_position()の部分を作りたいのですが・・
0238デフォルトの名無しさん
2007/05/22(火) 09:12:520239デフォルトの名無しさん
2007/05/22(火) 10:16:01みなさんありがとうございました。
0240デフォルトの名無しさん
2007/05/23(水) 15:19:02pageというのを持っていてページサイズ内なら一度に書き込みが出来ます
ページサイズは8〜256まで2のべき乗で、ROMタイプによって異なります。
今、EE_write(adr , size, dt[] ) という関数があって、この関数はページサイズを認識しません。
そこでこのラッパを作りたいのです
pagesize, ADR, SIZE , *p
if( (ADR ^ (ADR + SIZE -1)) & (0xFFFFu-(pagesize-1) ) ){ 一度に書ける }
分割しなければいけない場合
ADR 〜 (ADR | (pagesize-1) ) が最初に書く領域
というふうに考えたのだけど、ループが格好良く書けないの。
0241デフォルトの名無しさん
2007/05/23(水) 16:43:01結局こうやった
while(( (ADR ^ (ADR+SIZE-1)) & (0xFFFFU-(pagesize-1)) ) ){
ct = (ADR | (pagesize-1))+1 -ADR;
EE_write(ADR, ct , p);
p += ct;
ADR += ct;
SIZE -= ct;
}
EE_write(ADR, SIZE , p );
0242デフォルトの名無しさん
2007/05/24(木) 05:19:070243デフォルトの名無しさん
2007/05/25(金) 17:20:07普通に書くとこんな感じ?
unsigned tail = adr + size;
unsigned ct = pagesize - adr % pagesize;
while (adr + ct < tail) {
EE_write(adr, ct, dt);
dt += ct;
adr += ct;
ct = pagesize
}
if ((ct = tail - adr) != 0)
EE_write(adr, ct, dt);
>>241って、SIZEに 0 を指定されると大変なことになりそうだな。
0244デフォルトの名無しさん
2007/05/27(日) 15:33:150245デフォルトの名無しさん
2007/05/27(日) 15:35:130246デフォルトの名無しさん
2007/05/27(日) 22:25:320247デフォルトの名無しさん
2007/05/27(日) 23:15:480248デフォルトの名無しさん
2007/05/27(日) 23:26:39int, int って並びなら、
1, 2, 3, 4, 5, 6, 7, 8 が
4, 3, 2, 1, 8, 7, 6, 5 ってなるだけで
8, 7, 6, 5, 4, 3, 2, 1 にはならないのでは?
0249・∀・)っ-○◎●
2007/05/27(日) 23:31:17typedef union {
uint32_t wd;
uint8_t bt[4];
} HogeType;
HogeType a, b;
a.wd = src;
b.bt[0] = a.bt[3];
b.bt[1] = a.bt[2];
b.bt[2] = a.bt[1];
b.bt[3] = a.bt[0];
dest = b.wd;
0250デフォルトの名無しさん
2007/05/28(月) 00:21:290251デフォルトの名無しさん
2007/05/28(月) 00:52:56規格違反。
まあ、そう使えないコンパイラはないと思うけど。
0252デフォルトの名無しさん
2007/05/28(月) 08:09:580253デフォルトの名無しさん
2007/05/28(月) 10:29:21その理由が皆目検討つかないが。
0255デフォルトの名無しさん
2007/05/28(月) 15:48:22共用体のメンバのうち T 型の a というメンバに値が格納されているときは
U(!= T) 型の b というメンバの値は T 型の a に依存し、U 型の値としては
不正と見なされるため b を通してのアクセスは未定義の動作となる。
ではなぜ共用体が存在するのかというと、おそらく原始的なポリモーフィズムの
実現の為。
ある変数が複数通りの型(ここでは T と U とする)の値を受け入れる可能性が
あるとき、構造体のような、型の異なる複数の変数を用意するのは非効率のため
単一の変数で複数の型を扱える共用体を使う。
もっとも、C++では T 型と U 型の基本クラス V 型を定義して、V 型の参照として
T 型にも U 型にも(もちろん V 型にも)正規にアクセスできるので、共用体は
不要になってしまった(のだろう、たぶん)。
0256デフォルトの名無しさん
2007/05/28(月) 17:15:17enum Variant_Type {
VARIANT_INT,
VARIANT_DOUBLE,
VARIANT_CHAR,
VARIANT_STRING
};
struct Variant {
union {
int i;
double d;
char c;
char *s;
} value;
enum Variant_Type type;
};
/* var->type で分岐して、その内容を表示する関数 */
void Variant_show(const struct Variant *var) { ... }
int main(void) {
Variant var;
var.type = VARIANT_INT;
var.value.i = 4;
Variant_show(&var);
var.type = VARIANT_STRING;
var.value.s = "hoge";
Variant_show(&var);
}
0257デフォルトの名無しさん
2007/05/28(月) 22:18:41> もっとも、C++では T 型と U 型の基本クラス V 型を定義して、V 型の参照として
> T 型にも U 型にも(もちろん V 型にも)正規にアクセスできるので、共用体は
> 不要になってしまった(のだろう、たぶん)。
不要になってないだろ。
基本クラス云々で各種のデータを扱う処理は正規にできるようになったけど、
複数の型を同一の領域に割り付けるのは union でないとできない。
まあ、そんな機会はめったとないが。
0258デフォルトの名無しさん
2007/05/28(月) 22:22:43それで何の御利益があると思って書いてるんだろうか?
不思議な発想だとしか言いようがない
っていうか、それ多態じゃなくて多重定義でしょ?w
0259デフォルトの名無しさん
2007/05/28(月) 22:29:270260デフォルトの名無しさん
2007/05/28(月) 22:31:520261デフォルトの名無しさん
2007/05/28(月) 22:35:30共用体よりplacement newのほうが良いと思う。
0262デフォルトの名無しさん
2007/05/28(月) 22:36:54そして、それが内部的にどうなってるかとか、
そこでのコスト意識とかに至っては、全く考えた事ないんだろうね。
0263デフォルトの名無しさん
2007/05/28(月) 22:38:44共用体に入れられるのはそもそも POD 型だけだが、
ポインタで保持しておくことなら可能だな。
0264デフォルトの名無しさん
2007/05/28(月) 22:54:29> バリアント型とか知らないのかな。
C言語でそんなもん使う機会があまりないこととか知らないのかな。(w
0265デフォルトの名無しさん
2007/05/28(月) 22:59:440266デフォルトの名無しさん
2007/05/28(月) 23:06:160267デフォルトの名無しさん
2007/05/28(月) 23:11:53つーかビット演算スレでなぜ共用体…。
「そういう発想」というのは共用体をvariantとして使う発想ということかしら。
0268webmaster@気まぐれアナスイ
2007/05/28(月) 23:11:54ζ
!(+Φ_Φ)つ√ζ
+⊂. + 〆∂ {Ж}
"〆∂∂
〆〆
.:"
0269デフォルトの名無しさん
2007/05/28(月) 23:15:150270デフォルトの名無しさん
2007/05/28(月) 23:38:38でも共用体って記述した順番にメモリに保存されるかについて
仕様では未定義ですよね
0271デフォルトの名無しさん
2007/05/28(月) 23:40:46当たり前だろ。
つか struct の仕様と混同してないか?
0272デフォルトの名無しさん
2007/05/28(月) 23:43:42これはひどい
0273デフォルトの名無しさん
2007/05/28(月) 23:45:43このくらい常識だろ?
0274デフォルトの名無しさん
2007/05/28(月) 23:46:54typedef union {
uint32_t *pW;
uint8_t *pB;
} HogeType;
HogeType a;
uint8_t w;
a.pW = &src;
a.pB[0] ^= a.pB[3];
a.pB[1] ^= a.pB[2];
a.pB[2] ^= a.pB[1];
a.pB[3] ^= a.pB[0];
a.pB[0] ^= a.pB[3];
a.pB[1] ^= a.pB[2];
みたいなのが希望って事か?
0275デフォルトの名無しさん
2007/05/28(月) 23:49:33おかしくなるコンパイラもあるらしいよ。
俺はそういうの見た事無いけど。
0276デフォルトの名無しさん
2007/05/29(火) 00:13:33そういうコンパイラが現実にあるのかと言われても、んなこと知らん。
だが、顧客に「正常に動作することが保証されている」プログラムを提供するためには
仕様上未定義とされる書き方をしてはいけないし、意識せずしてしまったらバグとして扱われて然り。
0277デフォルトの名無しさん
2007/05/29(火) 00:20:530278デフォルトの名無しさん
2007/05/29(火) 00:32:45逆に、規格通り書いてもおかしくなることもある。
規格違反はそれはそれで重要だけど、
実際の処理系でどうなのかという方が時に重要な事もある。
ま、コメントとか残しておいて、
移植時にすぐ検索できるようにしておくべきではあるが。
0279デフォルトの名無しさん
2007/05/29(火) 00:44:32共用体の pW メンバに代入した場合、
pW の値しか正当性が保証されない。
そのため、pW に代入したすぐ後に pB を参照したとき、
規格ではその動作を保証しない。
uint32_t * と uint8_t * のアドレス表現が等しいという保証は無い。
この間のキャストで何らかの変換作業が生じる場合には、
このコードは正しく動かない。
そもそもアドレス演算は、配列要素へのポインタでしか保証されない
(配列風の参照では p[4] と *(p + 4) は等価で、
ここには p + 4 というアドレス演算が生じる)。
ここが原因で >>274 のようなことをすると
おかしくなる処理系があるという風に聞いている。
(「ハッカーのたしなみ」 の 87 ページを参照)
0280デフォルトの名無しさん
2007/05/29(火) 01:08:03ハッカーのたのしみ に一致する日本語のページ 約 26,800 件
0281デフォルトの名無しさん
2007/05/29(火) 01:15:260282デフォルトの名無しさん
2007/05/29(火) 10:36:39逆にいうとハードに強く依存する標準仕様はあってはならない。
もちろん環境が特定できる場合なら、エンディアンの違いを理解して使うぶんにはまったく問題ない。
むしろ同一アーキテクチャでならコンパイラのABIレベルではこういう部分も互換性が保障されてないと駄目。
そもそもエンディアンなんて標準仕様外のものを扱うのに、標準仕様を持ち出すほうがおかしいと思うがね
構造体などのデータアラインメントやABIの互換性は言語の規格じゃなくて
各CPUやOSのメーカー、コンパイラメーカーなど同士の取り決めで決まる。
つーか、暗黙の共通仕様や独自仕様にたよらないとTCP/IPすら扱えないぜ。
0283デフォルトの名無しさん
2007/05/29(火) 10:52:02データレイアウトを実装者で取り決める独自仕様が認められないなら、Cは危険な言語だな逆にいえば。
「仕様では未定義」は逆にいえば実装では各環境のABIに従ってきめていいということ。
0284デフォルトの名無しさん
2007/05/29(火) 11:17:39仕様上未定義を「未定義の動作」と混同していないか。
Cは移植性を高めるため、特定の環境に依存するような仕様はほとんど盛り込まれておらず
よって指摘の通り構造体のメモリ上でのレイアウトも定義されていない。
だが、メンバに正しくアクセスできることは保証されている。
0285デフォルトの名無しさん
2007/05/29(火) 11:25:400286デフォルトの名無しさん
2007/05/29(火) 11:38:48逆に>>349が意図しない動きをするコード吐くコンパイラって存在するなら教えてほしい。
変態のCellですら>>349が正しく動くことはABIレベルで保証されてる。
各型のレイアウトを厳密に定義してるからな。
0287デフォルトの名無しさん
2007/05/29(火) 11:43:140288デフォルトの名無しさん
2007/05/29(火) 12:21:19>>276
そして話題はループする。
ABIはCの言語仕様における実装依存の箇所を定めて厳密化するものなので
たとえABIの隙をかいくぐって自分の予期した挙動をさせることができたとしても
それは立派な規格違反。
あと、もし>>282さんと同一人物なら
>そもそもCの言語仕様で「未定義」な理由は、最初のバイトが最上位か最下位かはエンディアン依存だから。
これのソースを頼む。探しているんだが、見つからない(汗
0289デフォルトの名無しさん
2007/05/29(火) 12:27:18windows.hを使うのも規格違反だとか言い出しそうだな
0290デフォルトの名無しさん
2007/05/29(火) 12:34:19ちなみに、規格にないものを付け加えるのではなく、規格に抜けているを補うのがABI。
本来は規格に矛盾しないABIを定めなければならない。
ところでここはビット演算についてかたるスレなのか?
0291デフォルトの名無しさん
2007/05/29(火) 12:56:100292デフォルトの名無しさん
2007/05/29(火) 13:13:17「定義するな」なら違反になるが単に未定義のものに一定の動作保証をするだけなら違反じゃない。
何のために#pragmaが規格にあると思ってる。
処理系依存の拡張を、やっていいよと保証すらしてるのが規格だ。
ちなみにunion使った型変換はWindowsでは日常茶飯事だな。ULONG_INTEGERとか。
ここの住人がよく使うであろうMMXやSSEなんかはC用APIなんか、まさに共用体を使った型変換のオンパレード。
それでもパフォーマンスを求める客の「信頼」を得るためにすすんで使うものだ。
ANSI/ISO規格が絶対的に信頼されてて規格外のものは信頼されてないなんて独善的な言い分にすぎん。
getsみたいな危険な関数が野放しにされてるのはなんだね。
極論、信頼性の確保という面ではVC2005のセキュアCRT関数のほうが標準関数よりまとも。
ちなみにポインタをHANDLEという型にtypedefできるのは規定の動作。なんら問題ない。
0293デフォルトの名無しさん
2007/05/29(火) 13:37:270294デフォルトの名無しさん
2007/05/29(火) 14:40:400295デフォルトの名無しさん
2007/05/29(火) 15:10:330296デフォルトの名無しさん
2007/05/29(火) 15:14:490297デフォルトの名無しさん
2007/05/29(火) 17:55:34特定の環境では動くことが保証されてるかもしれないけど、
全ての環境で動く保証が無い。
だから、そのプログラムが特定の環境でのみ使用される事が決まってるなら、
規格違反でもその環境でちゃんと動作する事が保証されていれば問題ない。
ただ、色んな環境で使われるプログラムであれば、規格通りに作らないといけない。
つまりは要件次第の問題であって、常にどちらかでないといけないみたいな事を言うのは愚。
>>292
gets の使用は規格で推奨されていない。
未だ存在しているのは単に互換性のため。
セキュアCRT関数は安全だが、
GCC でコンパイルしたいような場合には
#if 使って GCC でも大丈夫なようにする必要がある。
あと、ハンドルで問題とされているのは、
ハンドルの値は別にアドレスではないのに
ポインタに入れるようにしている点。
ただ、これは int にしてしまうと安全性が低くなるし、
環境依存という程ちゃんと動かなくなる環境もないしで、
いい hack だと思う。
0298デフォルトの名無しさん
2007/05/29(火) 18:53:41ドラッグ&ドロップの処理などでGlobalAllocでメモリ確保したものを
HDROP型へキャストしてやるという事例がある。
ふうんと言われればそれまでのことだけど。
0299デフォルトの名無しさん
2007/05/29(火) 18:56:050300デフォルトの名無しさん
2007/05/29(火) 19:02:00昔、物理的なアドレスを使えば一意だろうと思って使ったら、見事に失敗した。
0301デフォルトの名無しさん
2007/05/29(火) 19:09:48#ハンドルの値は別にアドレスとは限らないのに
とするか。
0302デフォルトの名無しさん
2007/05/29(火) 19:13:49確かにメモリアドレス以上の情報を持ってることもあるけど、
C++ における「アドレス」ってのは、
そういう情報も含むんじゃないのかな。多分。
0303デフォルトの名無しさん
2007/05/29(火) 20:07:370304デフォルトの名無しさん
2007/05/29(火) 20:27:53どっかで見た。
0305デフォルトの名無しさん
2007/05/29(火) 20:36:020306デフォルトの名無しさん
2007/05/29(火) 21:00:160307デフォルトの名無しさん
2007/05/29(火) 21:24:50とか思ったけどそれはC++の話でしたねすいません
0308デフォルトの名無しさん
2007/05/29(火) 21:53:21別名: reference operator
0309・∀・)っ-○◎●
2007/05/30(水) 01:32:06「共用体を使った型変換は、保証されないとむしろ違反」
uint32とuint8[4]の完全なアドレス共用が保証できなければ
・各パートの先頭アドレスの一致
・char型(=1バイト)配列のデータ連続性
という規格で保証された動作に違反することになる。
断言する。
バイトオーダさえ一致すれば、共用体を使ったビット列の直接変換は保証できる。
つーか、規格にない動きまで保証されると規格【違反】なら、
Cコンパイラは現実のアーキテクチャ向けに実装された時点で違反を抱えることになり
空想の産物でなければならないことになるね。
規格外と規格違反を混同してるんじゃないの。
規格にない機能を実装したり独自の制約・動作保証をしたらいけないなんて規約は
規格に存在しない。
0310・∀・)っ-○◎●
2007/05/30(水) 01:35:52それでもさまざまなプラットフォームに移植されてるけどwwww
0311デフォルトの名無しさん
2007/05/30(水) 01:47:030312・∀・)っ-○◎●
2007/05/30(水) 01:59:18バイトオーダーの変換に共用体を持ち出すこと自体は俺としても感心しない。
HDの洗礼受けた人間ならこんな厨コードになるだろう
uint32 bswap(uint32 n) {
n = (n >> 16 | n << 16);
return ((n >> 8) & 0x00FF00FF) | ((n << 8) & ~0x00FF00FF);
}
こんなコードを書く間にもx86なら即値が使えるとか、
PowerPCならAND-NOT命令があるから定数ロードは1個だけでいいとか
アーキの特性を考えながら組む。
速くなるか遅くなるかも実装依存。それがビット演算厨の愉しみ。
書いた後で、「PPCとx86なら組み込みのBSWAPで十分な気もしてきた」とか思うのもまた一興。
0313デフォルトの名無しさん
2007/05/30(水) 02:07:16--
template<typename Type> static inline void endian(Type & val) {
union foo {Type t; char c[sizeof(Type)];} bar = {val};
std::reverse(bar.c, bar.c + sizeof(bar));
val = bar.t;
}
0314・∀・)っ-○◎●
2007/05/30(水) 02:11:59レジスタそのものが共用体なんですよ。
0315デフォルトの名無しさん
2007/05/30(水) 02:18:15template<> static inline void endian<int>(int & val) {
union foo {int t; char c[sizeof(int)];} bar = {val};
char tmp = bar.c[0]; bar.c[0] = bar.c[3]; bar.c[3] = tmp;
tmp = bar.c[1]; bar.c[1] = bar.c[2]; bar.c[2] = tmp;
val = bar.t;
}
--
これくらいの特殊化しておかないとw
ついでに言うと、これをどう最適化するかがコンパイラの腕の見せ所。
0316・∀・)っ-○◎●
2007/05/30(水) 02:21:07#include <algorithm>
#include <stdio.h>
template<typename Type> static inline void endian(Type & val) {
union foo {Type t; char c[sizeof(Type)];} bar = {val};
std::reverse(bar.c, bar.c + sizeof(bar));
val = bar.t;
}
int main()
{
unsigned int i = 0x12345678;
endian(i);
printf("0x%0X\n", i);
return 0;
}
[root@ps3 age]# spu-gcc test.cpp
[root@ps3 age]# ./a.out
0x78563412
0317デフォルトの名無しさん
2007/05/30(水) 02:33:39混同も何も、そもそも「規格外」とか「規格違反」とかいう用語は規格にあるのか?
0318デフォルトの名無しさん
2007/05/30(水) 02:35:52%08X っしょ。
0319・∀・)っ-○◎●
2007/05/30(水) 03:08:16よく最適化されたコードは、MMレジスタからpextrwで16ビットをeaxに転送した後、al, ahを使ってテーブル参照する。
0320デフォルトの名無しさん
2007/05/30(水) 08:24:42どいつもこいつもどうしてこう画一的・類型的で凡庸なんだろうなw
恐らく本人の自己イメージはその正反対なんだろうけどさ。
0321デフォルトの名無しさん
2007/05/30(水) 08:41:040322デフォルトの名無しさん
2007/05/30(水) 08:48:32あなたのその発言もまた 画一的・類型的で凡庸 な事に気付いてての発言だとすれば あなたは勇気がある。
気付いてないなら・・・・・
0323デフォルトの名無しさん
2007/05/30(水) 08:56:16ハッキリいってイルカよりもマグロの方が頭いいです。
人類の知能は一億年遅れてる。
0324デフォルトの名無しさん
2007/05/30(水) 14:10:270325デフォルトの名無しさん
2007/05/30(水) 20:38:320326デフォルトの名無しさん
2007/05/31(木) 01:08:470327デフォルトの名無しさん
2007/05/31(木) 01:34:420328デフォルトの名無しさん
2007/05/31(木) 04:34:030329デフォルトの名無しさん
2007/05/31(木) 09:31:520330デフォルトの名無しさん
2007/06/01(金) 01:04:55なんか体調によって味とか変わってくるらしいね。調子がいいときはどんな味がするん?
0331デフォルトの名無しさん
2007/06/01(金) 01:06:150332デフォルトの名無しさん
2007/06/01(金) 14:45:440333デフォルトの名無しさん
2007/06/01(金) 15:11:370334デフォルトの名無しさん
2007/06/01(金) 15:23:11それを言うなら「低俗化」では?
0335デフォルトの名無しさん
2007/06/01(金) 17:57:170336デフォルトの名無しさん
2007/06/01(金) 18:11:470337デフォルトの名無しさん
2007/06/01(金) 18:35:500338デフォルトの名無しさん
2007/06/01(金) 23:16:160339デフォルトの名無しさん
2007/06/02(土) 12:18:510340デフォルトの名無しさん
2007/06/03(日) 02:25:370341デフォルトの名無しさん
2007/06/03(日) 04:24:420342デフォルトの名無しさん
2007/06/19(火) 21:59:451100 1101 1111 1110 1010 1011 1001 1000
ってどんな意味のあるビット列ですか?
教えてください。
0343デフォルトの名無しさん
2007/06/19(火) 22:04:200344デフォルトの名無しさん
2007/06/19(火) 22:17:460345デフォルトの名無しさん
2007/06/19(火) 23:13:20generic( N : integer := 4 );
port( CK, RESET : in std_logic;
Y : out std_logic_vector(N-1 downto 0));
end GRAY_CODE_COUNTER;
architecture BEHAVIOR of GRAY_CODE_COUNTER is
signal GRAY, COUNT : std_logic_vector(N-1 downto 0);
begin
process ( RESET, CK ) begin
if ( RESET = '1' ) then
COUNT <= (others => '0');
elsif ( CK'event and CK = '1' ) then
COUNT <= GRAY;
end if;
end process;
process (COUNT)
variable BIN : std_logic_vector(N-1 downto 0);
begin
BIN(N-1) := COUNT(N-1);
for I in N-2 downto 0 loop
BIN(I) := BIN(I+1) xor COUNT(I);
end loop;
BIN := BIN + 1;
GRAY(N-1) <= BIN(N-1);
for I in N-2 downto 0 loop
GRAY(I) <= BIN(I+1) xor BIN(I);
end loop;
end process;
Y <= COUNT;
end BEHAVIOR;
0346デフォルトの名無しさん
2007/06/19(火) 23:15:550347デフォルトの名無しさん
2007/06/20(水) 12:26:09たとえば、機械類なんかの位置あわせの目的で センサーを配置する時に
4入力あれば16箇所の位置を特定できるわけだけど
同時に2つのセンサーが変化するようになってると巧くゆかない。
そこで移動につれて、一つしかセンサーが変化しないような配置方法を考えたのがそのコード。
0348デフォルトの名無しさん
2007/06/20(水) 14:21:1101 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16
って意味
0349デフォルトの名無しさん
2007/06/20(水) 18:58:030350デフォルトの名無しさん
2007/06/20(水) 19:07:000351デフォルトの名無しさん
2007/06/20(水) 19:09:5100 01 11 10 この順番で動けば 順方向 逆方向なら 00 10 11 01 と動くので区別出来る
2進数 00 01 10 11 でいいじゃないと思うだろうけど これだと一度に2ビット変化する箇所が2度出来る
センサーの取りつけに物凄い精度が要求される事になり安価なマウスに採用出来ない
0352デフォルトの名無しさん
2007/06/21(木) 00:53:520353デフォルトの名無しさん
2007/06/21(木) 01:35:520354デフォルトの名無しさん
2007/06/21(木) 01:46:36それ、具体的に教えて。
0355デフォルトの名無しさん
2007/06/21(木) 23:48:280356デフォルトの名無しさん
2007/06/21(木) 23:55:04どこだっけかな・・・。
0357デフォルトの名無しさん
2007/06/22(金) 01:08:450358デフォルトの名無しさん
2007/06/22(金) 01:17:060359デフォルトの名無しさん
2007/06/22(金) 07:26:57ttp://www.tensyo.com/urame/date/dayTips.shm
ここの後ろの方にビットマスクと繰り返し演算で剰余を求める方法がある
0360デフォルトの名無しさん
2007/06/22(金) 07:35:523、4回の演算で書けたような気が・・・って、俺の記憶違いか?
0361デフォルトの名無しさん
2007/06/22(金) 07:37:370362デフォルトの名無しさん
2007/06/22(金) 07:40:38あれ? 乗算だっけ?
0363デフォルトの名無しさん
2007/06/22(金) 07:42:310364デフォルトの名無しさん
2007/06/22(金) 07:50:41B=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回ちょっとのループか
0365デフォルトの名無しさん
2007/06/22(金) 08:00:17a = ( (a>>12)<<3 ) + a & 4095; を 前段でやれば改善するんじゃないかな
0366デフォルトの名無しさん
2007/06/22(金) 09:49:4156で割るロジックをコンパイルしたら、-1840700269を掛けた後に
ビットシフトと足し算をしていた。それ以上追っかけるのはパス。
0367デフォルトの名無しさん
2007/06/22(金) 09:51:15LARGE_INTEGER li;
li.QuadPart = UInt32x32To64(a>>3,0x24924925);
int d = li.HighPart;
a -= ((d<<3)-d)<<3;
aがsigned intの場合は、もう少し複雑。
0368デフォルトの名無しさん
2007/06/22(金) 10:11:460369デフォルトの名無しさん
2007/06/22(金) 10:17:291チップとかだと 掛算はビットサイズに応じたサイクル数かかるし
掛け算持ってないCPUもあるし
0370デフォルトの名無しさん
2007/06/22(金) 10:21:390371デフォルトの名無しさん
2007/06/22(金) 10:26:29a = ( (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;
これならどうだろ?
0372デフォルトの名無しさん
2007/06/22(金) 10:34:31素直にdiv使った方が速いかもしれない。
0373デフォルトの名無しさん
2007/06/22(金) 10:45:500374デフォルトの名無しさん
2007/06/22(金) 11:08:06最初は
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ビットづつしか落とせない。 無理
0375デフォルトの名無しさん
2007/06/22(金) 11:17:53a = ( (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回のループでいいか
0376デフォルトの名無しさん
2007/06/22(金) 11:26:49div 命令は、持っていてもbit数のサイクルかかるのが殆どだよ。 だから >>366-367 のような最適化がされるんだし
0377デフォルトの名無しさん
2007/06/22(金) 11:33:210378デフォルトの名無しさん
2007/06/22(金) 11:37:09ここまでしても idiv より速いのか・・・。
0379デフォルトの名無しさん
2007/06/22(金) 11:48:18整数乗算は レイテンシ4、スループット1/ サイクル
除算は浮動小数点ユニットで行われ
FDIV 命令 レイテンシ: 単精度17 サイクル、倍精度36 サイクル、拡張精度56 サイクル
だから、桁違いにレイテンシが大きい。
0380デフォルトの名無しさん
2007/06/22(金) 11:50:390381デフォルトの名無しさん
2007/06/22(金) 11:58:11除算ってのはコストのわりに利用頻度が少ないから、どうせ浮動小数点ユニットもってるからそっちで計算させてるのさ
仮に、整数演算ユニットで除算をしたとしても、結局32サイクルはかかるし、その間加減算比較ユニットの一つが潰れてしまうからな
0382デフォルトの名無しさん
2007/06/22(金) 12:14:11そら遅いわな。
0383デフォルトの名無しさん
2007/06/22(金) 12:27:02これ以上はスレ違いになるがつっこませてくれ。
浮動小数点ユニットがIEEE754(だったっけ)で処理する場合、単精度で23ビット、倍精度で52ビットの精度だろ。
被序数が32ビット整数ならともかく、64ビット整数の除算は精度の問題上アウトだぞ。
0384デフォルトの名無しさん
2007/06/22(金) 12:34:23Intel 系の浮動小数点ユニットは
拡張倍精度(80ビット/仮数部64ビット)で行われてるから大丈夫。
0385デフォルトの名無しさん
2007/06/22(金) 12:44:20まじか!と思って何年も開いていない重たいバインダーを紐解いてみたら、たしかにそう書かれているな。
しかも本当は63ビット精度なのに、ケチりビットをケチらない荒技で対処してるし・・・。
そのうえx87コプロに限ればつねに拡張倍精度で計算されることになってたりして、もうね、馬(ry。
0386デフォルトの名無しさん
2007/06/22(金) 13:02:46x % 56 = (x % 7)<<3 + (x & 7)
x/7 を round(2^32/7 )>>32 で近似したのが >>367
0387デフォルトの名無しさん
2007/06/22(金) 13:07:240388デフォルトの名無しさん
2007/06/22(金) 13:08:100389デフォルトの名無しさん
2007/06/22(金) 16:51:54実際に速度を比較してみれば?
Cの場合、&より+の方が優先順位が高いので、
>>375の&演算には括弧が必要だね。
0390デフォルトの名無しさん
2007/06/22(金) 17:06:590391デフォルトの名無しさん
2007/06/22(金) 18:03:24function 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 命令より速い
0392デフォルトの名無しさん
2007/06/22(金) 18:06:180393デフォルトの名無しさん
2007/06/22(金) 18:09:150394デフォルトの名無しさん
2007/06/22(金) 18:33:37for 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
0395デフォルトの名無しさん
2007/06/22(金) 18:40:43ビット演算 思ったよりガンバレるな。
0396デフォルトの名無しさん
2007/06/22(金) 19:24:47ひどい場合は書き直しすら命じられまする(´・ω・`)
0397デフォルトの名無しさん
2007/06/22(金) 19:44:350398デフォルトの名無しさん
2007/06/22(金) 20:36:07高級言語の目的の一つが可読性の向上だからね。
コメントで解説いれても却下される場合すらあると思うよ。
0399デフォルトの名無しさん
2007/06/22(金) 20:48:20x % 60 が欲しい時とか、いちいち変換が大変だよな
0400デフォルトの名無しさん
2007/06/22(金) 21:47:03可能なら、最適化の一環としてコンパイラに組み込むのがベストだが。
0401デフォルトの名無しさん
2007/06/22(金) 23:23:020402デフォルトの名無しさん
2007/06/23(土) 00:18:01ほんとにやってる?やらない場合も多いけど
絶対さぼってる
0403デフォルトの名無しさん
2007/06/23(土) 01:26:200404デフォルトの名無しさん
2007/06/23(土) 01:29:46定数割り算の掛け算化が行われない例があれば、逆に教えて欲しい。
まさか、最適化オプションを指定しないとしてくれないなんて言わないよね。
0405デフォルトの名無しさん
2007/06/23(土) 01:31:50深く考えず単純に引き算かと
今考えると空恐ろしいやり方だw
0406デフォルトの名無しさん
2007/06/25(月) 10:58:280407デフォルトの名無しさん
2007/06/25(月) 19:13:340408デフォルトの名無しさん
2007/06/25(月) 19:57:27浮動小数点ユニットが無い時には除算も無かったと思ったのかな
除算そのものはシフト減算比較の繰り返しで出来るから
サイクル数さえ必要なだけかければマイクロプログラム方式ならそうコストかからない
掛け算と変わらない。
0410デフォルトの名無しさん
2007/06/26(火) 08:23:37変数での剰余になると、結局コードで書いても加え戻し法(復元法)とかになるので
除算命令使った方がやっぱり速い。
0411デフォルトの名無しさん
2007/06/28(木) 00:42:510412デフォルトの名無しさん
2007/07/08(日) 16:40:57ということは除算命令自体はマクロになるのかな
0413デフォルトの名無しさん
2007/07/08(日) 18:16:200414デフォルトの名無しさん
2007/07/08(日) 19:57:330415デフォルトの名無しさん
2007/07/11(水) 22:50:580416デフォルトの名無しさん
2007/07/21(土) 07:45:05マイクロプログラムで処理してるんだろ
>8086のマイクロコードは、命令長が21ビットで、プログラムサイズは504ステップであった
0417デフォルトの名無しさん
2007/07/21(土) 10:07:540418デフォルトの名無しさん
2007/07/21(土) 21:50:220419デフォルトの名無しさん
2007/08/03(金) 07:04:320420デフォルトの名無しさん
2007/08/03(金) 11:40:010421だんごの輪島
2007/08/03(金) 12:15:430422デフォルトの名無しさん
2007/08/03(金) 21:06:030423デフォルトの名無しさん
2007/08/12(日) 09:53:590424デフォルトの名無しさん
2007/08/12(日) 10:01:530425デフォルトの名無しさん
2007/08/12(日) 14:27:310426デフォルトの名無しさん
2007/08/14(火) 10:07:390427デフォルトの名無しさん
2007/08/14(火) 11:48:050428デフォルトの名無しさん
2007/08/16(木) 20:39:500429デフォルトの名無しさん
2007/08/18(土) 23:05:500430デフォルトの名無しさん
2007/08/18(土) 23:09:420431デフォルトの名無しさん
2007/08/20(月) 01:29:30アドバイス頼む。
アドレスのアライメントをチェックするためにポインタをintにキャストして
&でビットテストしてる。
extern char *p;
if(((int)p & 3) == 0){
//32bit境界にある処理…
}
だけどアドレスをintにキャストするのは64bit時代的に行儀悪いみたい。
でもアドレスをビットテストしたいという状況は普通にあると思うんで、
こういう場合C系的にはどう書くのが上手な作法なの?
0432デフォルトの名無しさん
2007/08/20(月) 01:38:30Linux界隈じゃ unsigned long へのキャストが一般的とされてるが
個人的には嫌い
0433デフォルトの名無しさん
2007/08/20(月) 01:40:500434デフォルトの名無しさん
2007/08/20(月) 08:48:310435デフォルトの名無しさん
2007/08/20(月) 23:58:100436デフォルトの名無しさん
2007/08/21(火) 00:11:510437デフォルトの名無しさん
2007/08/21(火) 00:33:140438デフォルトの名無しさん
2007/08/21(火) 00:37:000439・∀・)っ-○◎●
2007/08/21(火) 00:52:140440デフォルトの名無しさん
2007/08/21(火) 01:00:010441・∀・)っ-○◎●
2007/08/21(火) 01:19:060442デフォルトの名無しさん
2007/09/09(日) 23:01:400443デフォルトの名無しさん
2007/09/09(日) 23:35:230444デフォルトの名無しさん
2007/09/09(日) 23:37:250445デフォルトの名無しさん
2007/09/09(日) 23:45:200446デフォルトの名無しさん
2007/09/16(日) 06:34:050447デフォルトの名無しさん
2007/09/19(水) 12:28:310448デフォルトの名無しさん
2007/09/19(水) 12:32:110449デフォルトの名無しさん
2007/09/19(水) 13:50:160450デフォルトの名無しさん
2007/09/19(水) 23:03:560451デフォルトの名無しさん
2007/09/19(水) 23:56:290452デフォルトの名無しさん
2007/09/20(木) 00:04:430453デフォルトの名無しさん
2007/09/20(木) 18:42:49ガ
0454デフォルトの名無しさん
2007/09/22(土) 00:43:27これもっと簡単にならないかな?
0455デフォルトの名無しさん
2007/09/22(土) 07:06:58--------------------
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;
}
--------------------
0456デフォルトの名無しさん
2007/09/27(木) 20:24:000457デフォルトの名無しさん
2007/09/29(土) 23:03:31or
int rotate_0_9(int a){a++;return(a+((a+6)>>4)*6)&15;}
引数が0〜8の時1を加算し、引数が9の時0を返す。
0458デフォルトの名無しさん
2007/09/29(土) 23:17:240459デフォルトの名無しさん
2007/09/29(土) 23:39:430460デフォルトの名無しさん
2007/09/29(土) 23:58:360461デフォルトの名無しさん
2007/09/30(日) 00:06:340462デフォルトの名無しさん
2007/09/30(日) 00:15:35>>458
>>460
どれが速い?
0463デフォルトの名無しさん
2007/09/30(日) 00:20:180464デフォルトの名無しさん
2007/09/30(日) 00:34:05cl /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が圧倒的だった(俺もそう思ってた)
ソースに続く
0465デフォルトの名無しさん
2007/09/30(日) 00:34:50----------------------------
#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;
}
----------------------------
0466デフォルトの名無しさん
2007/09/30(日) 00:38:34と変更して計算結果も表示してみたら>>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)
0467デフォルトの名無しさん
2007/09/30(日) 00:40:00static int t[10]={1,2,3,4,5,6,7,8,9,0};
return t[a];
}
表引き。
これもやってみてくれ。
0468デフォルトの名無しさん
2007/09/30(日) 00:49:01やってみるよ。
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
無茶苦茶だった。
0469デフォルトの名無しさん
2007/09/30(日) 00:55:09rotate_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
0470デフォルトの名無しさん
2007/09/30(日) 00:57:00int rotate_0_9_458(int a){return ++a%10;}
に修正してる
0471デフォルトの名無しさん
2007/09/30(日) 01:13:29; 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
見るからに遅そうな
0472デフォルトの名無しさん
2007/09/30(日) 01:16:44; 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以上だったら脂肪
0473デフォルトの名無しさん
2007/09/30(日) 01:27:47平均的には>460がいいんだろうな。
0474デフォルトの名無しさん
2007/09/30(日) 02:05:05確かに、別の環境だと逆転してたり。
#Celeron [email protected] 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 [email protected] 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)
0475デフォルトの名無しさん
2007/09/30(日) 04:40:29でも実際の仕事では0〜99のローテートでも%で書いたりするなあ。
0476デフォルトの名無しさん
2007/09/30(日) 08:29:400477デフォルトの名無しさん
2007/09/30(日) 09:14:400478デフォルトの名無しさん
2007/09/30(日) 10:11:46入力が必ず0〜9なら
a=((a+7)&15)-6; // 0〜8 が 1〜9 9が-6
(aの符号拡張か 4bitの算術右シフト結果)のビット反転と and
0479457
2007/09/30(日) 23:43:500480デフォルトの名無しさん
2007/09/30(日) 23:45:02すまん、逆に遅くなりそうだ。
0481デフォルトの名無しさん
2007/10/01(月) 16:44:480482デフォルトの名無しさん
2007/10/01(月) 17:41:590483ヽ・´∀`・,,)っ━━━━━━┓
2007/10/04(木) 02:56:19一般的には商と剰余は同時に求めることが可能
0484デフォルトの名無しさん
2007/10/21(日) 17:07:330485デフォルトの名無しさん
2007/10/21(日) 18:36:55http://www.tensyo.com/urame/date/dayTips.htm#MOD
縛りを入れるともっと高速化出来そう…
0486デフォルトの名無しさん
2007/10/23(火) 00:23:052018か2019
4049か4050
であるか判別する方法は4回比較するしか
ないかな?
0487デフォルトの名無しさん
2007/10/23(火) 00:49:07bool check(int value) {
const int mask = ~1;
if( (value & mask) == 2018 || ((value + 1) & mask) == 4050 ) return true;
return false;
}
0488デフォルトの名無しさん
2007/10/23(火) 01:56:04bool check(int value) {
const int mask = ~1;
if (((abs(value - 3034) + 1) & mask) == 1016) return true;
return false;
}
0489デフォルトの名無しさん
2007/10/23(火) 09:11:06比較4回に比べてリーダビリティは下がってる。
0490デフォルトの名無しさん
2007/10/23(火) 09:53:31case 2018: case 2019: case 4049: case 4050:
doit();
}
0491デフォルトの名無しさん
2007/10/23(火) 11:06:26return 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
いろいろ測ってみた
コンパイラやマシンによって違うと思うけど
0492デフォルトの名無しさん
2007/10/23(火) 11:25:06入力が多数回で、4つの値が均等にバラつくという条件にしたら、最後まで演算しない4回比較
がイイかと思えますが。
0493デフォルトの名無しさん
2007/10/23(火) 11:26:33可読性も考慮するの?このスレで?
0494デフォルトの名無しさん
2007/10/23(火) 11:29:150495デフォルトの名無しさん
2007/10/23(火) 12:45:37# 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
0496デフォルトの名無しさん
2007/10/23(火) 21:35:27アセンブリコードで比較してみると分かるんじゃね?
0497デフォルトの名無しさん
2007/10/23(火) 23:12:05if(v==2018||v==2019){
}else if(v==4049||v==4050){
}else{
}
って条件に読めるんだが
0498デフォルトの名無しさん
2007/10/23(火) 23:17:570499デフォルトの名無しさん
2007/10/24(水) 00:23:34日本語でおk
やっと言う側に回れたか
0500デフォルトの名無しさん
2007/10/24(水) 01:05:28いや、今日きちんとみかか村に出撃して
糞仕様について問い詰めてきたけど
case 2018: case 2019: case 4049: case 4050:
で正しい
どうもみんなありがとう
0501デフォルトの名無しさん
2007/11/02(金) 19:56:43>if (((abs (v - 3034) + 1) & mask) == 1016) return 1;
ここら辺の数値の導き方教えてください
どいった関係で3034とか出すの?ど素人ですんません
0502デフォルトの名無しさん
2007/11/02(金) 20:15:082018+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
0503デフォルトの名無しさん
2007/11/02(金) 21:44:43ものっそい感動しました
久しぶりに成長した気がする
この括り方すげー
0504デフォルトの名無しさん
2007/11/03(土) 20:48:030505デフォルトの名無しさん
2007/11/04(日) 06:35:340506デフォルトの名無しさん
2007/11/04(日) 08:47:47サイズなら、((bin/16)<<4) | (bin%16) ・・・バイト版。 <99のチェックは必要。
ワードは、/100の商と余りに分けて、上のを呼び、合成。
自分で書いたのはこんな当たり前の奴だなあ・・・
0507デフォルトの名無しさん
2007/11/10(土) 16:03:38また状況変った?
0508デフォルトの名無しさん
2007/11/10(土) 16:47:46メモリアクセス速度とキャッシュアクセス速度の比率
によって変わるからなあ
細かくいいだすとキャッシュ方式も絡むし
結局「場合による」んじゃねえの
0509デフォルトの名無しさん
2007/11/10(土) 17:28:19ただ、この場合の「一般」というのは、分岐が含まれる(=分岐ミスの可能性がある)という前提。
例えば上の((bin/16)<<4) | (bin%16) の場合だと
依存関係が2箇所あって、その部分は同時実行は出来ないけど
キャッシュアクセスに要する数クロック程度の時間と比べてどちらが速いかはわからんね。
テーブルジャンプ(ほぼ同じ値が続く場合以外)は糞だけど。
0510デフォルトの名無しさん
2007/11/10(土) 17:37:190511デフォルトの名無しさん
2007/11/10(土) 18:06:010512506
2007/11/11(日) 02:32:03キャッシュ云々の話はなし。/100だけは除算ルーチン使わないとだめだった。
0513デフォルトの名無しさん
2007/11/11(日) 13:44:020514デフォルトの名無しさん
2007/11/14(水) 11:40:49655*( x + x/2048 + x/16384)/ 65536
0515デフォルトの名無しさん
2007/11/14(水) 14:14:260516デフォルトの名無しさん
2007/11/14(水) 15:57:51while ( x-y*100>=100 ) y++;
ならせいぜいループ1回だろ
0517デフォルトの名無しさん
2007/11/14(水) 18:05:590518デフォルトの名無しさん
2007/11/14(水) 18:34:29(42949672*x+65536)>>32
0519デフォルトの名無しさん
2007/11/15(木) 07:36:11>>514-516 は、たぶん数学的には同等なような気がする。
>>518 それ、どういう原理なの? 32シフトしたら全部なくなっちゃうような気が・・・
0520デフォルトの名無しさん
2007/11/15(木) 08:53:19x386なら32x32bit掛け算の結果が2つのレジスタに判られるから 32bitシフトは上位のレジスタを採用するだけになる。
0521デフォルトの名無しさん
2007/11/15(木) 11:57:03>>32
0522デフォルトの名無しさん
2007/11/15(木) 12:18:01>>32
0523デフォルトの名無しさん
2007/11/15(木) 12:22:04>>522
何が言いたいのか意味不明だ。
0524デフォルトの名無しさん
2007/11/15(木) 12:29:420525デフォルトの名無しさん
2007/11/15(木) 12:42:20x >> 32
0526デフォルトの名無しさん
2007/11/15(木) 12:44:230527デフォルトの名無しさん
2007/11/15(木) 13:11:18こうすればいいのよ(たぶん)
0528527
2007/11/15(木) 13:12:44吊ってくるorz
0530デフォルトの名無しさん
2007/11/15(木) 16:54:121/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度繰り返す
0531デフォルトの名無しさん
2007/11/16(金) 01:35:070532デフォルトの名無しさん
2007/11/16(金) 08:46:49余りは後から y=x/N を求めた後 x-N*y で求めればいい
余りだけが必要なら355付近から話題が出てる
0533デフォルトの名無しさん
2007/11/16(金) 09:53:08動かしてみる辛さ
0534デフォルトの名無しさん
2007/11/16(金) 10:26:25パソコンの除算命令はレイテンシが大きいから連続して実行させるととても重くなる。
ただ整数ユニットでは実行されないから、その間に他の命令を入れられるならOK
あ、このスレか、>>367-379
0535デフォルトの名無しさん
2007/11/16(金) 10:59:280536デフォルトの名無しさん
2007/11/16(金) 11:03:080537デフォルトの名無しさん
2007/11/16(金) 11:04:470538デフォルトの名無しさん
2007/11/16(金) 11:23:21作ってくれ
0539デフォルトの名無しさん
2007/11/16(金) 11:26:26たぶんレジスタ動作 + 演算より、メモリ動作は遅いんだろう
0540518
2007/11/16(金) 11:39:24ループの中で定数(変数でも変わらなければOK)で除算するのは、
置き換えた方が高速化できるし、それを実際に使っている。
ピクセル操作のような回数の多いループでは劇的な効果がある。
>>539
それは毎回キャッシュから外れた場合の話。
オンキャッシュなら少しでもCPUを止めない方がいい。
0541デフォルトの名無しさん
2007/11/16(金) 11:45:08で、分母はいくらなの? 100の場合はいろいろ出てるよね。
0542デフォルトの名無しさん
2007/11/16(金) 11:46:27例えば2〜500まで定数だけ作って分岐させて使う
そのとき高速になるのか?
0543デフォルトの名無しさん
2007/11/16(金) 11:48:53たとえば関数テーブルで分岐したとしても、キャッシュミスを起こすだろう。
0544518
2007/11/16(金) 11:50:14できる。
それぐらいなら除数の逆数のテーブルを使って可能。分岐はさせないほうがいい。
ただ、16bit全域とかになると、テーブルの方が不利になるCPUが多い。
0545デフォルトの名無しさん
2007/11/16(金) 11:54:520546デフォルトの名無しさん
2007/11/16(金) 11:57:240547デフォルトの名無しさん
2007/11/16(金) 12:00:462〜1024までなら10回の分岐で決定する 10回程度のループを使うなら分岐させた方が良い
0548デフォルトの名無しさん
2007/11/16(金) 12:01:09(A*x+B)のA,Bをテーブルにするの?
でも、たとえば 65535÷3はどうするの?A=21845にしたら、これでは無理だよね
0549デフォルトの名無しさん
2007/11/16(金) 12:10:410550518
2007/11/16(金) 12:12:05そうそう。Bは固定でいい。
16ビット範囲の X / Dなら、R = 4294967295 / D として、
X / D の値は (R * X + 65536) >> 32となる。
Dが複数あるなら、D→Rのテーブルを作ればOK
0551デフォルトの名無しさん
2007/11/16(金) 12:14:16BCC5.5だけど、上のやつ計算できなかったよ
0552518
2007/11/16(金) 12:19:40__asm{
mov eax, R
mul X
add eax, 010000h
adc edx, 0
mov eax, edx
}
0553デフォルトの名無しさん
2007/11/16(金) 13:04:33Rが切り捨てなら汎用になるように
(R * X + R - 1 ) >> 32
でいいんじゃないの?
0555デフォルトの名無しさん
2007/11/16(金) 13:24:060557デフォルトの名無しさん
2007/11/16(金) 14:03:01(A * x + A-1 ) >> B
として AのMSBが1になるように B を調整するって事だよね?
Bは常に32以上だから、実際には上位ワードだけを>>(B-32) するのだろうけど
0558518
2007/11/16(金) 17:10:53いや、そうじゃなくて、余計なA - 1 という演算を使うのではなく、
550の式を32ビットに拡張すればいいってこと。
32ビット範囲の X / Dなら、R = ((1 << 64) - 1) / D として、
X / D の値は (R * X + (1 << 32)) >> 64となる。
0559デフォルトの名無しさん
2007/11/17(土) 04:25:26ルネサスのマニュアルによるとシフト演算と割り算に迷ったら割り算の方が大抵速いみたいなことが書いてあったけど
0560デフォルトの名無しさん
2007/11/17(土) 07:26:500561デフォルトの名無しさん
2007/11/17(土) 07:28:200562デフォルトの名無しさん
2007/11/17(土) 12:16:142で割るのを1ビットシフトするぐらいはいいけど、あえて複雑な演算にするほど処理能力を求められないでしょ?普通の開発は。
でも、このような議論って技術者としては面白いし、ある意味大切だよね。
0563デフォルトの名無しさん
2007/11/17(土) 12:40:03アルゴリズム上の話で、実際に64bit乗算をするわけではないと思う。
元ネタはこれじゃね?
ttp://www.emit.jp/prog/prog_div.html
0564デフォルトの名無しさん
2007/11/17(土) 13:51:33コンパイラがやってくれることもしばしば。
まぁ尤も、コンパイラのアセンブリ出力を見たときに「割り算がない」って悩まないためにも
知識はあったほうがいいのだけれどね。
0565デフォルトの名無しさん
2007/11/17(土) 13:57:31Dが16bitの範囲なら Rは 48bitって事になるぞ。 64bitモードに以降しないと効率悪いぞ
0566デフォルトの名無しさん
2007/11/17(土) 14:00:28D=100の場合
1 : ( x * 4294967200 + 65536) >> 32
2 : ( x * 4294967200 + 4294967199 >> 32
のどっちが 大きな x までまともに計算出来るかって問題でしょ?
0567デフォルトの名無しさん
2007/11/17(土) 14:01:491 : ( x * 42949672 + 65536 ) >> 32
2 : ( x * 42949672 + 42949671 ) >> 32
0568デフォルトの名無しさん
2007/11/17(土) 15:24:56内部で32+24ビット程度しか保持していない気がする
0569デフォルトの名無しさん
2007/11/17(土) 15:33:51テストプログラム作ったけど上位1ビットの値は壊れているようだ
#include <iostream>
using namespace std;
main(){
int n;
for(n=50;n<=64;n++)
cout<<n<<" "<<(unsigned int)((1<<n)>>(n-1))<<endl;
}
0570デフォルトの名無しさん
2007/11/17(土) 15:43:451になるはずですよね?
cout << (unsigned int) ( ((1<<64)-2) >> 63 );
0571デフォルトの名無しさん
2007/11/17(土) 17:43:47-1を unsigned にキャストしてるんだからUINT_MAXになると思う。
0572デフォルトの名無しさん
2007/11/17(土) 18:06:100573ヽ・´∀`・,,)っ━━━━━━┓
2007/11/17(土) 19:18:14unsigned __int64かunsigned long longでおk
0574ヽ・´∀`・,,)っ━━━━━━┓
2007/11/17(土) 19:20:40なんで普通のコンピュータで使えるビット数越えたシフト使うんだ。
1 << 64なんてオーバーフローで0になること確定じゃないか。
0575デフォルトの名無しさん
2007/11/17(土) 20:42:480576デフォルトの名無しさん
2007/11/17(土) 23:58:43>>563のコードと同じだからそっちでやってみればいいんじゃないか。
0577デフォルトの名無しさん
2007/11/18(日) 07:54:51using 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の値が変わるのはなぜ?
0578デフォルトの名無しさん
2007/11/18(日) 08:34:36サイズを超えるシフトは未定義。
0579デフォルトの名無しさん
2007/11/18(日) 22:48:230580デフォルトの名無しさん
2007/12/03(月) 22:55:090581デフォルトの名無しさん
2007/12/03(月) 23:13:14a + b * 65536 などと表示して、32bit以上を表現したら
ハードウェア搭載の除算よりビット演算のほうが速い?
除算が現れたらintを16bit数に変換して計算する
0582デフォルトの名無しさん
2007/12/04(火) 05:02:29(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除法を高速化出来るか?
0583582
2007/12/04(火) 05:12:330584デフォルトの名無しさん
2007/12/16(日) 20:25:38if (bResult == 0 || bResult == -1)
じゃなくて、一発で調べる方法はないですか?
0585デフォルトの名無しさん
2007/12/16(日) 20:42:350586デフォルトの名無しさん
2007/12/16(日) 21:10:400587デフォルトの名無しさん
2007/12/16(日) 21:30:22定義を調べた方が良さそう。
0588デフォルトの名無しさん
2007/12/16(日) 22:05:41ttp://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpwinui/html/_win32_getmessage.asp
0589デフォルトの名無しさん
2007/12/16(日) 22:08:460590デフォルトの名無しさん
2007/12/16(日) 22:37:380591デフォルトの名無しさん
2007/12/16(日) 22:42:19同じ3演算だけど-1をロードしないだけ早いかも?
uint32_tがいいかどうかはよくわからない。
0592デフォルトの名無しさん
2007/12/17(月) 00:16:010593デフォルトの名無しさん
2007/12/17(月) 00:26:58( ・д⊂ヽ゛
0594デフォルトの名無しさん
2007/12/17(月) 00:29:32>警告 GetMessage 関数は、0 以外の値、0、-1 のいずれかを返します。したがって、次のようなコードは避けてください。
そもそも…
0595デフォルトの名無しさん
2007/12/17(月) 00:30:540596デフォルトの名無しさん
2007/12/17(月) 00:39:34右シフト・条件分岐より、比較・条件分岐の方が速くない?
if (((uint32_t)bResult + 1) <= 1)
0597デフォルトの名無しさん
2007/12/17(月) 00:50:04マシン語レベルでは結局0比較に変換されるから同じ程度じゃないかな。
でもCレベルではそっちの方が短くていいと思う。
0598デフォルトの名無しさん
2007/12/17(月) 01:17:11ちょっと前まで主流だった某CPUではシフトは加減算の
8倍遅かったし、それ以外のCPUでも演算器の関係で
シフトの方が並列化されにくいかも、とかそういう話。
0599デフォルトの名無しさん
2007/12/17(月) 01:19:210600デフォルトの名無しさん
2007/12/17(月) 02:05:250601デフォルトの名無しさん
2007/12/17(月) 03:12:30そんなこと言うならこのスレの意義って一体なんなのさ。
確かにWindows APIをそんなアホみたいに呼ぶ事はないだろうが、
こんな風に一般化してみれば、それなりに使い道はあるだろ。
_Bool bounds_check(int n, int lower, int upper)
{
return (unsigned)(n - lower) < (unsigned)(upper - lower);
}
>>600
加減算よりシフトの方が速いCPUなんてあるのかな?
演算の頻度からいっても普通は加減算を最速に設計すると思うけど。
x86系を数種類しか触った事ないから、他にはあるのかも知れないが。
0602デフォルトの名無しさん
2007/12/17(月) 04:47:19小さい加算器を作ったことがあればわかるはず
クロック数が一緒ってことはあるかもしれんが、
シフトの方が遅いってことはまずないだろう
0603ヽ・´∀`・,,)っ━━━━━━┓
2007/12/17(月) 05:39:05分岐は極端に遅いなんていうのはCellプログラマだけにしてください。
0604デフォルトの名無しさん
2007/12/17(月) 07:41:05このケースは1bitだからその通りだけど
x86の8086-286までは、2bit以上のシフトは遅かったんだよ。
最初は直接bit数指定のインストラクションすらなかったし。
0605デフォルトの名無しさん
2007/12/17(月) 13:11:190606デフォルトの名無しさん
2007/12/17(月) 13:13:10単純な分岐なら、if文使ってコンパイラに任せた方が速いね。
絶対値求める時とか、NULLならreturnするとか、分岐コストかからなくていい。
0607デフォルトの名無しさん
2007/12/17(月) 14:37:02俺もbool型オンリーの方が好きだが、スクリプト言語してるとそうじゃない方が多い気がする。
0608デフォルトの名無しさん
2007/12/17(月) 18:27:510609デフォルトの名無しさん
2007/12/17(月) 18:33:360610デフォルトの名無しさん
2007/12/17(月) 19:02:560611デフォルトの名無しさん
2007/12/17(月) 21:34:17で充分でね?
0612デフォルトの名無しさん
2007/12/17(月) 21:49:47シフタってのはデータセレクタの塊だから多ビットのシフトは
シリコンの面積を喰うのよ
0613デフォルトの名無しさん
2007/12/17(月) 23:54:21-1以外の負の値が未定義
0614デフォルトの名無しさん
2007/12/17(月) 23:54:340615デフォルトの名無しさん
2007/12/17(月) 23:58:16は
if (((uint32_t)bResult + 1) <= 1)
と同じコードになったぞ。
gcc賢いな。
ちなにみRISCでどうなるか見たかったので団子の嫌いなCELLのgccでコンパイルしたw
ちなみにCELL(SPE)もヒントブランチあるから。
むしろARMのプリディケーションいまいちだと思うけど。
0616ヽ・´∀`・,,)っ━━━━━━┓
2007/12/18(火) 00:11:17Cellのスカラ性能が
気に食わない
0617ヽ・´∀`・,,)っ━━━━━━┓
2007/12/18(火) 00:45:11しかも二重に使うとハングする致命的なバグ持ちだから始末に困る
0618デフォルトの名無しさん
2007/12/18(火) 00:47:470619ヽ・´∀`・,,)っ━━━━━━┓
2007/12/18(火) 00:52:150620デフォルトの名無しさん
2007/12/18(火) 08:10:080621デフォルトの名無しさん
2007/12/18(火) 11:30:400622デフォルトの名無しさん
2007/12/18(火) 20:46:310623デフォルトの名無しさん
2007/12/21(金) 07:08:360624デフォルトの名無しさん
2007/12/21(金) 07:18:070625デフォルトの名無しさん
2007/12/30(日) 10:37:000626デフォルトの名無しさん
2008/01/03(木) 18:36:52ダンゴさんすげえな
0627デフォルトの名無しさん
2008/01/09(水) 19:20:080628デフォルトの名無しさん
2008/01/14(月) 22:47:230629デフォルトの名無しさん
2008/01/21(月) 23:54:190630デフォルトの名無しさん
2008/01/22(火) 00:09:06x1 = 0xFF842144
x2 = 0x5400FF33
ユーザからの入力u1、u2が入力された場合
考えられるケースは以下の4つになると思います。
・u1=x1、u2=x2一致
・u1=x1一致
・u2=x2一致
・どちらとも一致しない
最低3回比較しないとどのケースか判断できないって
思い込んでるのですが
何かいいアイディアくれる人いませんか?
0631デフォルトの名無しさん
2008/01/22(火) 00:46:32しかし、そんあ80年代前半のBASICの論理式みたいなアナクロな発想をするって
今日日奇特な人だね。
0632デフォルトの名無しさん
2008/01/22(火) 00:50:58・u1=x1一致、u2=x2一致
・u1=x1一致、u2=x2不一致
がある
u1がx1と一致しないケースに
・u1=x1不一致、u2=x2一致
・u1=x1不一致、u2=x2不一致
がある
つまり4通り
比較は最大2回
0633デフォルトの名無しさん
2008/01/22(火) 01:21:290634デフォルトの名無しさん
2008/01/22(火) 01:30:35p = x1 XOR x2
の値を取得しておく
q1 = p XOR u1
q2 = p XOR u2
を得る
0635ヽ・´∀`・,,)っ━━━━━━┓
2008/01/22(火) 01:30:560636デフォルトの名無しさん
2008/01/22(火) 01:54:14得た後はどうすればいいのw?
q1とq2をどうやって使うの?
0637デフォルトの名無しさん
2008/01/22(火) 02:56:20>・u1=x1一致、u2=x2一致
あんた馬鹿?
0638デフォルトの名無しさん
2008/01/22(火) 11:10:15無理だろ,あれは and と andnot だから.pcmpeqd の方が良さげ
0639デフォルトの名無しさん
2008/01/22(火) 11:49:49if( u1 == x1 ) {
if( u2 == x2 ) {
//ryouhou
} else {
//u1 nomi
}
} else {// not
if( u2 == x2 ) {
//u2 nomi
} else {
//ryouhou itti sinai
}
}
どこも間違ってるように思えないんだが。
0640デフォルトの名無しさん
2008/01/22(火) 12:34:57ここがどういうスレかを考えれば、>>630が何を聞きたいか
多少説明不足でもだいたい分かるだろ普通w
0641デフォルトの名無しさん
2008/01/22(火) 13:13:100642デフォルトの名無しさん
2008/01/22(火) 18:32:50b1 = (u1 == x1)
b2 = (u2 == x2)
return a[(b1 << 1) | b2];
0643642
2008/01/22(火) 18:33:45○ int a[] = {一致しない, 片方一致, 片方一致, 両方一致};
0644デフォルトの名無しさん
2008/01/23(水) 10:32:39それがないと、減算して、さらに1引いてキャリーを出してローテートしなくちゃいけない
アキュムレータが2個しかないCPUなら
AccA := u1-x1-1;
RotWithC(AccB);
AccA := AccA+x1+1-x2-1;
RotWithC(AccB);
AccB := AccB and 3;
結局、そのあたり何が効率的かはアセンブラで見ないといけないけど
アセンブラで出来る高速化は、リニアにしか効かないから、そんなに意味ないんだよね
0645デフォルトの名無しさん
2008/01/23(水) 20:55:340646デフォルトの名無しさん
2008/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");
}}
0647646
2008/01/24(木) 15:42:1832bitの割り算も出来るけど646は16bit同士です
0648デフォルトの名無しさん
2008/01/24(木) 15:52:260649デフォルトの名無しさん
2008/01/24(木) 17:46:02gcc のカオス・スパゲッティ状態を知らぬようだな。
勧めるならせめて Small-C くらいにしとけ。
このルーチンなら 工学社から出ていた
Small-C ハンドブックにもちゃんと説明されていたんだし。
0650デフォルトの名無しさん
2008/02/04(月) 20:42:37これから読みますノシ
0651デフォルトの名無しさん
2008/02/05(火) 23:53:510652ヽ・´∀`・,,)っ━━━━━━┓
2008/02/06(水) 01:12:310653デフォルトの名無しさん
2008/02/22(金) 06:50:560654デフォルトの名無しさん
2008/02/28(木) 07:49:510655デフォルトの名無しさん
2008/03/01(土) 13:50:550656デフォルトの名無しさん
2008/03/05(水) 07:05:430657デフォルトの名無しさん
2008/03/11(火) 07:43:250658デフォルトの名無しさん
2008/03/24(月) 22:44:220659デフォルトの名無しさん
2008/03/30(日) 21:00:530660デフォルトの名無しさん
2008/03/30(日) 21:42:47でも懐かしい。
0661デフォルトの名無しさん
2008/04/06(日) 18:17:38|
/ ̄ ̄ ̄ ̄ ̄ ̄
<⌒/ヽ-、___
/<_/____/
0662デフォルトの名無しさん
2008/04/06(日) 18:41:010663デフォルトの名無しさん
2008/04/06(日) 19:46:300664デフォルトの名無しさん
2008/04/07(月) 17:04:46http://vivi.dyndns.org/W/254
0665デフォルトの名無しさん
2008/04/07(月) 19:44:18この表現は凶悪だな。何故なら、高速にならなかった場合にはかなり遅くなる可能性があるからだ。
0666デフォルトの名無しさん
2008/04/17(木) 06:42:520667デフォルトの名無しさん
2008/05/01(木) 06:01:450668デフォルトの名無しさん
2008/05/01(木) 08:02:290669デフォルトの名無しさん
2008/05/01(木) 08:50:520670ヽ・´∀`・,,)っ━━━━━━┓
2008/05/01(木) 18:55:250671デフォルトの名無しさん
2008/05/09(金) 19:08:22スレ立てるまでもない質問はここで 第91刷
http://pc11.2ch.net/test/read.cgi/tech/1209716212/171
以下の条件で、32bit値のハミングウェイトが素数か否かを判定する
出来るだけ高速な方法を探しています
・入力はランダム
・(最悪ではなく)平均速度が速いことが望ましい
・0、1は素数ではない(偽になって欲しい)
・ハミングウェイトそのものの値は必要ない
・64bit拡張などは必要ない。32bit決め打ちで良い
・外部メモリはあまり使いたくない
皆様のお知恵を貸していただけませんでしょうか
0672デフォルトの名無しさん
2008/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;
}
0673デフォルトの名無しさん
2008/05/09(金) 21:56:140674デフォルトの名無しさん
2008/05/12(月) 10:32:410675デフォルトの名無しさん
2008/05/12(月) 18:51:0264bit が int の場合では結果は明らかに異なるよな
0676デフォルトの名無しさん
2008/05/12(月) 20:19:590677デフォルトの名無しさん
2008/05/12(月) 20:51:310678ヽ・´∀`・,,)っ━━━━━━┓
2008/05/12(月) 21:34:450679デフォルトの名無しさん
2008/05/12(月) 21:44:21別に変数1つをレジスタ1つで扱えないといけないわけじゃないし
問題ないんじゃね?
0680デフォルトの名無しさん
2008/05/12(月) 21:47:550681ヽ・´∀`・,,)っ━━━━━━┓
2008/05/12(月) 21:59:190682デフォルトの名無しさん
2008/05/13(火) 11:50:540683デフォルトの名無しさん
2008/05/13(火) 11:56:230684デフォルトの名無しさん
2008/05/13(火) 12:39:16体型が肉団子だからだよな。
0685ヽ・´∀`・,,)っ-○◎●
2008/05/13(火) 12:47:46━━━━━━┓がどうみたらだんごに見えるねん
あたまわるいんとちゃうか
0686ヽ・´∀`・,,)っ鹵〜<巛巛巛
2008/05/13(火) 12:50:400687デフォルトの名無しさん
2008/05/13(火) 14:33:310688デフォルトの名無しさん
2008/05/13(火) 16:51:030689デフォルトの名無しさん
2008/05/13(火) 18:15:31と、だけ書くのもなんだから、ちょこっとマジレス。
ANSI C での int の定義は処理系依存で、CPUのレジスタ幅によるらしい。
なので、Z80 なら 8bit の筈だけど、
大体のZ80 C処理系では char=8bit, int=16bit と扱う。
なんで int は 16bit より大きいという誤解があるんだろうなぁ。
その昔は char=7bit なんで処理系もあったというので、
油断は出来ないように思うんだよ。
0690デフォルトの名無しさん
2008/05/13(火) 18:38:03昔の話は知らん
0691ヽ・´∀`・,,)っ━━━━━━┓
2008/05/13(火) 19:01:17http://www.d1.dion.ne.jp/~ytera/1bitcpu.htm
0692デフォルトの名無しさん
2008/05/13(火) 21:12:11今は規格に準拠した処理系であれば int >= 16 bits なのは真理。
あと、int のサイズの定義は CPU のレジスタ幅にして欲しそうな定義ではあるけど、
そう断言している訳じゃない。
実際最近でも 64-bit マシンで int = 32-bit のことがある。
>その昔は char=7bit なんで処理系もあったというので、
無い。
0695デフォルトの名無しさん
2008/05/14(水) 03:04:090696デフォルトの名無しさん
2008/05/14(水) 23:42:41それとの勘違いだろ。(7bit があったかどうかは知らん。)
まあ単位が 6bit なのは uart と同じ理由だが。
0697デフォルトの名無しさん
2008/05/15(木) 02:07:52それはCPUと言うよりリレーの置き換えみたいなもの
Connection Machineのはまともな1bit CPUだけどbit sliceだから何bitにでも
化ける
0698デフォルトの名無しさん
2008/05/28(水) 00:29:010699デフォルトの名無しさん
2008/05/30(金) 00:17:23こんなビットがあったとき、0が4と5ビット目に
存在するってどうやって調べるのが効率いいのかな?
個数はわかるけど位置はどうすりゃいいんだろう
0700デフォルトの名無しさん
2008/05/30(金) 00:34:240701デフォルトの名無しさん
2008/05/30(金) 02:40:1111100111 and 00011000
0702デフォルトの名無しさん
2008/05/30(金) 02:41:22シフト回数で判別。
0703デフォルトの名無しさん
2008/05/30(金) 02:50:48ループ
0704デフォルトの名無しさん
2008/05/30(金) 09:37:40>>701
aビット目とbビット目が動的に変わるなら、マスク作ってandとった方が良いかもしれない。
0705デフォルトの名無しさん
2008/05/30(金) 09:47:01問題文は正確に
0706デフォルトの名無しさん
2008/05/30(金) 11:48:474、5ビット目というのは変わりうるのよね?
あと個数が2個というのも変わりうるのよね?
0707デフォルトの名無しさん
2008/05/30(金) 11:51:01ああ、あと、いつもがそんな風に左右対称とは限らないのよね?
0708デフォルトの名無しさん
2008/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 になるまで繰り返せばいい
0709デフォルトの名無しさん
2008/06/11(水) 00:25:23それって並列にできないですかね
無理ですよね.....
0710デフォルトの名無しさん
2008/06/11(水) 00:30:28みんなどんなふうに宣言しますか?
C/C++でのバターな方法が解りません
0711デフォルトの名無しさん
2008/06/11(水) 00:34:460712デフォルトの名無しさん
2008/06/11(水) 00:41:57普通ループではカウンタを++していくと思うけど、
(iを1,2,3・・・と加算)
一回処理するごとに左に1ビットシフトしていた。
(iを1,2,4,8・・・とシフト)
普通こういうコード書きます?仕事で。
0713デフォルトの名無しさん
2008/06/11(水) 00:49:431989年ぐらいに見た記憶があるw
0714デフォルトの名無しさん
2008/06/11(水) 01:15:510715デフォルトの名無しさん
2008/06/11(水) 01:26:180716デフォルトの名無しさん
2008/06/11(水) 01:27:14普通にあるし、速度面だけでなく、その方が可読性があるものもある。
0717デフォルトの名無しさん
2008/06/11(水) 01:28:540718デフォルトの名無しさん
2008/06/11(水) 07:07:30こういうの?
0719デフォルトの名無しさん
2008/06/12(木) 22:51:520720デフォルトの名無しさん
2008/06/12(木) 23:56:44どうするの?
0721デフォルトの名無しさん
2008/06/13(金) 08:21:14普通にカウントしろよw
0722デフォルトの名無しさん
2008/06/13(金) 11:54:06泣くしかない
0723デフォルトの名無しさん
2008/06/25(水) 13:20:16の1バイト目・2バイト目の値を求める方法をお願いします。
0724デフォルトの名無しさん
2008/06/25(水) 13:24:45貴方の小人は頭から食べるのですか? お尻から食べるのですか?
http://www.aozora.gr.jp/cards/000912/files/4673_9768.html
0725デフォルトの名無しさん
2008/06/25(水) 19:29:149x9なのでSSE2使えば128ビットレジスタ一個に収まるのでかなりの高速化が出来ると思っています。
囲碁のルールに上下左右を全て囲まれた石の塊は盤から取り除かれるというのがありますが、
これを高速に行うにはどうしたらよいでしょうか。
問題はSSE2は128ビットを一塊としたシフトが行えないことで、これのせいでどうしたらよいかわからなくなっています。
よろしくお願いします。
0726デフォルトの名無しさん
2008/06/25(水) 19:48:230727デフォルトの名無しさん
2008/06/25(水) 20:02:15そうです。
モンテカルロはスピード命らしいので、SSEを使えないかと思っています。
0728デフォルトの名無しさん
2008/06/25(水) 21:11:080729デフォルトの名無しさん
2008/06/25(水) 21:49:090730デフォルトの名無しさん
2008/06/25(水) 21:53:24x64環境を使っていいのならビット単位をやめてバイト単位にして
16本のXMMレジスタを9本使って9x9にした方がいいんじゃないかな?
0731デフォルトの名無しさん
2008/06/25(水) 22:23:24バイト単位にしたほうが有利なんですか?
0732デフォルトの名無しさん
2008/06/25(水) 23:18:330733デフォルトの名無しさん
2008/06/26(木) 06:48:29その場合、ビット単位の操作は可能です。
x64でレジスタが16本あったとしても通常のレジスタを9本も占めるというのは考えにくいですが、
XMMレジスタなら9本使っても支障ないということでしょうか?
0734デフォルトの名無しさん
2008/06/26(木) 09:01:44最大9bitしかシフトしないでしょ? なら 境界にデータを置かなければいいでしょ
あるいは16bitを1列にしてレジスタ2つにしたらどう?
0735デフォルトの名無しさん
2008/06/26(木) 10:08:36x64で汎用レジスタが増えたとはいえ9本も使えばループや分岐に支障が出ると思うよ。
その点XMMレジスタなら浮動小数点演算しなければ基本的に空いてる。
0736725
2008/06/26(木) 19:15:01すいません。
皆さんにレスしていただいておいて申し訳ないのですが、
高速化について調べていたらGPGPUというのが見つかりました。
グラボに計算をさせるというものなのですが、上手くツボにはまれば
CPUの何十倍もの速度がでるそうです。
囲碁がはたしてグラボに計算させるのに向いてるのかどうかわかりませんが、
SSEは一旦忘れて、GPGPUについて調べてみようと思います。
グラボも3〜4万だせば結構いいのが買えるみたいです。
とりあえずGPGPUスレとCUDAスレにいって雰囲気つかんできます。
皆さんのレスには感謝しています。
失礼しました。
0737デフォルトの名無しさん
2008/06/26(木) 19:47:500738デフォルトの名無しさん
2008/06/26(木) 21:47:07普通にCPUで計算するより遅かった
0739デフォルトの名無しさん
2008/06/26(木) 22:43:05CUDAするなら前もって、GPUに計算させたい部分
設計しておけ
わしは今日から3日でモンテカルロをCUDAで解けるように
勉強する
0740725
2008/06/27(金) 00:03:02どもです。
ところで最新ハイエンドGPUはピーク性能1TFLOPS超えるらしいですね。
HDDもテラバイトの物が出てるし、時代はもうテラなんですねぇ。
0741デフォルトの名無しさん
2008/06/27(金) 00:18:19Radeon HD3870とGeforce9800GTXもってるけど
両方とも労せず2000スレッド以上生成して並列に計算できるよ
0742デフォルトの名無しさん
2008/06/27(金) 00:32:16一命令ではできないが,シフトしたいビット数を n として n/8 と n%8
とに分けてシフト命令使って後で合成すれば可能
0743デフォルトの名無しさん
2008/06/27(金) 04:00:39enumの様に贅沢にintを丸々一つ石に配分した方が良かったかもしれないね。
0744デフォルトの名無しさん
2008/06/27(金) 07:18:19ビット演算じゃないけど
0745デフォルトの名無しさん
2008/07/11(金) 01:01:510746デフォルトの名無しさん
2008/07/20(日) 15:56:270747デフォルトの名無しさん
2008/07/20(日) 20:41:050748デフォルトの名無しさん
2008/07/20(日) 23:07:22の
・式
ってとこに詳しく書いてるだろ...読みもしないで不思議とか言うな
0749デフォルトの名無しさん
2008/07/20(日) 23:07:590750デフォルトの名無しさん
2008/07/22(火) 10:17:230751デフォルトの名無しさん
2008/08/01(金) 03:07:44なるべくループやlogを使わない物がいいです
0754デフォルトの名無しさん
2008/08/01(金) 04:04:46[512]=9 演算はこれが最速。
0755デフォルトの名無しさん
2008/08/01(金) 04:06:47if( n & 0x200 ) return 9;
if( n & 0x100 ) return 8;
・・・
if( n & 0x002 ) return 1;
0756デフォルトの名無しさん
2008/08/01(金) 04:15:160757デフォルトの名無しさん
2008/08/01(金) 04:39:50bsf(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; //解なし
}
0758デフォルトの名無しさん
2008/08/01(金) 04:41:33bsf(bits){
bits-=1;
int num;
num = (bits >> 1) & 03333333333;
num = bits - num - ((num >> 1) & 03333333333);
num = ((num + (num >> 3)) & 0707070707) % 077;
return num;
}
0759デフォルトの名無しさん
2008/08/01(金) 04:52:26ありがとうございます。みんなカッコイイ
0760デフォルトの名無しさん
2008/08/01(金) 05:52:52char bit[256] = { 0,1,2,0,3,0,0,0, 4,0,0,0,0,0,0,0, 略 };
の間違いだった。
んで結果を-1すれば合うんじゃないかな。
0761デフォルトの名無しさん
2008/08/01(金) 06:23:57int 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;
}
0762デフォルトの名無しさん
2008/08/01(金) 10:45:430763デフォルトの名無しさん
2008/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];
0764762
2008/08/01(金) 16:32:34そしてそっちのハッシュのほうが優れているね。
0765デフォルトの名無しさん
2008/08/01(金) 16:55:450766デフォルトの名無しさん
2008/08/01(金) 17:47:48異次元過ぎてついて行けないのだが解説頼む
0767デフォルトの名無しさん
2008/08/01(金) 21:25:31gperfとかで完全ハッシュ関数を作るのと同じように
(文字列ではなく)特定の数字から対応する特定の数値への完全ハッシュ関数を作っているんだと思う。
どうやって導いたかなんて知らん。
0768デフォルトの名無しさん
2008/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ビットのことか。
確かに小さいほうがメモリとキャッシュに優しいですな。
という感じであってますか。
>どうやって導いたかなんて知らん。
俺も知りたい。
0769デフォルトの名無しさん
2008/08/02(土) 01:52:050770デフォルトの名無しさん
2008/08/02(土) 01:56:270771デフォルトの名無しさん
2008/08/02(土) 10:03:58ソースに組み込むときは、その演算の意味とメリットなど
ビット演算を導入した経緯や思想も書いてほしい・・・
ソース理解に時間がかかったり、修正が大変・・・
まあ、俺がお馬鹿なのかもしれないけど。
あと、763って751からの流れなんですか?
それとも別の流れ?
0772デフォルトの名無しさん
2008/08/02(土) 10:14:13>まあ、俺がお馬鹿なのかもしれないけど。
が正解。
0773デフォルトの名無しさん
2008/08/02(土) 10:17:05771みたいなバカもいる。
バカはROMっていろ!死ね771!!
0774それは俺か (w
2008/08/02(土) 10:59:130775デフォルトの名無しさん
2008/08/02(土) 11:02:09ttp://www.ic-net.or.jp/home/takaken/nt/slide/hash.html
これか?
>>762は本当に頭がいい。>>763の書き込みがなかったら
意味も解らずスルーするところだった。
0776デフォルトの名無しさん
2008/08/02(土) 12:58:48分かった気がする。
0777デフォルトの名無しさん
2008/08/02(土) 13:59:12でも、保守する奴が >>762 みたいに頭いいとは限らんから、
仕事のプログラムなら >>754-755 あたりのほうがいいと思う。
0778デフォルトの名無しさん
2008/08/02(土) 14:04:14>>762みたいなのが許されるのは趣味のプログラミングだけだよ。
0779デフォルトの名無しさん
2008/08/02(土) 16:19:14ビックリするほど容量が無いプラットフォームとか、
コンパイラが準備されてなくてアセンブラで書かなきゃいけないような場合、
更にRISCみたいに見た目と実行順が違うような環境だと
読む量が少ない短いコードが逆に役に立つ。
自慢を理由に書くと間違いなく死を招く。
0780デフォルトの名無しさん
2008/08/02(土) 16:20:19今でもまだまだ、速度やサイズ重視の分野はあるし。だいぶ少なくはなっているけど。
0781デフォルトの名無しさん
2008/08/02(土) 16:32:120782デフォルトの名無しさん
2008/08/02(土) 16:36:450783デフォルトの名無しさん
2008/08/02(土) 16:49:03入らなくなり削りに削って「400byteだけ下さい!」と上司に嘆願したのは懐かしい思い出。
0784デフォルトの名無しさん
2008/08/02(土) 18:57:37それは同意だけど、 >>762 のエッセンスを抜き出して、わかりやすくすれば
いいんじゃないかな
おそらく、2^a を掛けると aビット左シフトする、というのは誰にも自明だけど
1〜9の値にマップするマジック定数がややトリッキーかと
なら、見た目にわかりやすいようシフト数を4倍にして、(ついでに右シフトにして)
こんな感じでどうだろうかね(64ビット整数が使えることが前提だけど^^)
/* assume that n is 2^a (1<=a<=9) */
return (0x9876543210LL / ( n * n * n * n )) & 0xf;
0785デフォルトの名無しさん
2008/08/03(日) 02:24:010786デフォルトの名無しさん
2008/08/03(日) 02:37:3364bit整数があるにしても、nが32bitならn*nで64bitでしょ。中間結果でbitが失われるんじゃ?
0787デフォルトの名無しさん
2008/08/03(日) 02:40:550788デフォルトの名無しさん
2008/08/03(日) 02:55:56関係ないがa&(-a)で右端の一ビットを得られるぞ、左端は無理じゃないか
0789デフォルトの名無しさん
2008/08/03(日) 03:17:470790デフォルトの名無しさん
2008/08/03(日) 03:41:51どうもです、今見た資料に左端を操作する命令列は存在しないって書いてあったorz
0791デフォルトの名無しさん
2008/08/03(日) 03:56:210792デフォルトの名無しさん
2008/08/03(日) 03:59:50a = ( ( 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 );
0793784
2008/08/03(日) 17:00:12もちろん変数n は64ビット長
LP64なら long型だと思ってもらえばいいです
演算量については、いまどきの投機実行するCPUなら
下手に条件判定入るよりは速いと思うけど、・・・まあ状況次第ですね
0794デフォルトの名無しさん
2008/08/03(日) 17:25:070795デフォルトの名無しさん
2008/08/03(日) 18:31:31「シンプルにしようや」
で終わってしまうんですよね〜
そうすると、754や755に落ち着くのかな・・・
0796デフォルトの名無しさん
2008/08/03(日) 19:39:21よほど特段の理由が無い限り、シンプルが一番。
0797デフォルトの名無しさん
2008/08/03(日) 19:51:280798デフォルトの名無しさん
2008/08/03(日) 21:10:392^9まででしょ?
0799デフォルトの名無しさん
2008/08/03(日) 21:12:540800デフォルトの名無しさん
2008/08/03(日) 21:51:460x3 * 0x3 => 9
0x7 * 0x7 => 0x31
0xf * 0xf => 0xe1
0xff * 0xff => 0xfe01
0xfff * 0xfff => 0xffe001
0xffff * 0xffff => 0xfffe0001
0xfffff * 0xfffff => 0xffffe00001
これに規則性みたいなものを感じるんですが、
何か法則があるんでしょうか?
0801デフォルトの名無しさん
2008/08/03(日) 21:54:519*9=81
99*99=9801
999*999=998001
と同じようなもんだろ
0802デフォルトの名無しさん
2008/08/03(日) 22:06:41インド人のほうが面白い発想しそうだね
0803デフォルトの名無しさん
2008/08/03(日) 22:09:362進数に考えれば、最初から綺麗に並ぶよ。
1 * 1 = 1
11 * 11 = 1001
111 * 111 = 11001
1111 * 1111 = 11100001
11111 * 1111 = 1111000001
0804デフォルトの名無しさん
2008/08/03(日) 22:16:490xffff0000 - 0xffff => 0xfffe0001
特に面白い事実はなさそうだが
0805デフォルトの名無しさん
2008/08/03(日) 22:21:59これが国民機ナンバーの正体かー
すると8801は?
93.8136 * 93.8136 = 8800.99
収束しないのか
0806デフォルトの名無しさん
2008/08/03(日) 22:22:360807デフォルトの名無しさん
2008/08/03(日) 22:25:250808デフォルトの名無しさん
2008/08/03(日) 22:34:480809デフォルトの名無しさん
2008/08/03(日) 23:10:510810デフォルトの名無しさん
2008/08/03(日) 23:48:03あえて8801に意味を見出すなら99*99-1100とかなんとか
0811デフォルトの名無しさん
2008/08/03(日) 23:49:53俺頭大丈夫k
0812デフォルトの名無しさん
2008/08/04(月) 00:08:26こういった力(ちから)を持つ数字が隠されていた影響に違いない。
その証拠に型番が9821に変わろうとしたとたん没落した。
きっと9801のままなら永遠の存在だったんだよ。
0813デフォルトの名無しさん
2008/08/04(月) 00:11:55ハッシュって、必要の都度、bit数見極めて作らなきゃいけないんだな・・・
0814デフォルトの名無しさん
2008/08/04(月) 01:24:271.実用性がある
2.比較的わかりやすい
ビット演算のアルゴリズムって何だろうね・・・
0815デフォルトの名無しさん
2008/08/04(月) 01:50:11例えばコメントに
// 762氏ハッシュ
とか書けるぐらいに。
0816デフォルトの名無しさん
2008/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"がいまいち良くわかりません。
0817デフォルトの名無しさん
2008/08/04(月) 02:06:280818デフォルトの名無しさん
2008/08/04(月) 02:06:59コメントに絶対に書かなきゃいけないのは、>>751-752だよ。
どういう実装をしたかのコメントなんて二の次三の次。
それなのに仕様のコメントを怠ったままで「すげーテクニック使ってるんだぜ」的なコメントを残しても意味なし。
そんなものを残すぐらいなら、(最低限の>>751-752の他に)assertでも使った範囲チェック入れとけ。
もちろん、>>762のやり方に対するコメント(完全ハッシュ関数とテーブル)はあった方が良い。
けど、仕様についてのコメントの方がはるかに重要。
0819デフォルトの名無しさん
2008/08/04(月) 03:06:570820デフォルトの名無しさん
2008/08/04(月) 03:45:030821デフォルトの名無しさん
2008/08/04(月) 04:32:520822デフォルトの名無しさん
2008/08/04(月) 04:59:250823デフォルトの名無しさん
2008/08/04(月) 08:02:17...;
#else // 速度重視で書き換え
...;
#endif
0824デフォルトの名無しさん
2008/08/04(月) 08:15:04何でこのスレにいるかって?
知るために見ているのさ
0825デフォルトの名無しさん
2008/08/04(月) 09:53:070826デフォルトの名無しさん
2008/08/04(月) 12:37:57スペース(0x20)より小さい値のcharは 「\8進数」 で書く約束になってる。
"\1\2\3・・・"は、char xxx[ ]={ 1, 2, 3, ・・・, 0 };という配列が生成される。
0827デフォルトの名無しさん
2008/08/04(月) 13:33:40>スペース(0x20)より小さい値のcharは 「\8進数」 で書く約束になってる。
なってない。
0828デフォルトの名無しさん
2008/08/04(月) 17:24:05俺のはLSIC85とか adUc51とか、クミコ系ばっかりで、ANSIは知らないけど。
0829デフォルトの名無しさん
2008/08/04(月) 18:13:000830デフォルトの名無しさん
2008/08/04(月) 22:15:16こんな感じだったと思うけど、よく覚えてないや
x:src y:dest
s=(x*0x02020202)&0x84422010
t=(x<<3)&0x420
y=(s+t)%1023
0831デフォルトの名無しさん
2008/08/04(月) 22:49:390832デフォルトの名無しさん
2008/08/04(月) 23:59:20\n \t \r とかもあるわけで。
0833デフォルトの名無しさん
2008/08/05(火) 00:45:34は?
0834デフォルトの名無しさん
2008/08/05(火) 01:21:35どうも「文字リテラル+[]」が良くわからん。
ビット演算うんぬんではなく・・・
C言語でこれを書いてコンパイルが通るのか?
どうもこのスレに付き合うには、大学などできちんと学ぶか
元々、この手のことが好きじゃないとついていけませんね・・・
社会人になってから、プログラムを覚えたアホアホな俺の
プリンみたいな脳みそでは、だめかorz
0835デフォルトの名無しさん
2008/08/05(火) 01:37:17char * buf = "01234567";
char a = buf[0];
が判れば、
char a = "01234567"[0];
だって判るだろ。
0836デフォルトの名無しさん
2008/08/05(火) 01:41:46こんなのもある。これが直感的に納得しづらいというのはワカランでもないけど、
char a = "01234567"[0];
こっちは普通だべ。
0837デフォルトの名無しさん
2008/08/05(火) 09:00:56>元々、この手のことが好きじゃないとついていけませんね・・・
当たり前だと思うんだが。
0838デフォルトの名無しさん
2008/08/05(火) 10:50:52プロセスメモリエディタかバイナリエディタと睨めっこでもしてみればいいんじゃね。
0839デフォルトの名無しさん
2008/08/05(火) 12:25:02プログラムの中に埋め込まれるちょっと特殊なchar[]にすぎん。
"hoge"とか書いた場合、これはそういう配列を暗黙にどっかに確保しろよと
コンパイラに言っているのと同時に、式の中で評価されるときは、その(無名の)
char配列の名前と同等に扱われる。
要はchar[]なのだから、char*な変数に文字列リテラルを代入したり
printf()のような関数に文字列リテラルを引数として渡したり、ということは
普通に・当然のようにやっているはずだ。
さすがにprintf("hello, world"); というコードを見たことが無いとは言わせない。
ならば、[]演算子を適用できるということも当然分かるはずだな。
多分、そういうコードを今まで見たことが無い、見慣れない、ってだけだろう。
0840デフォルトの名無しさん
2008/08/05(火) 12:32:50[]を特殊なものだと思うからいけない。ただの演算子だ。
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]; ならわかるだろ。。
0841デフォルトの名無しさん
2008/08/05(火) 13:15:16配列の名前[インデックス]
のように教えてる参考書の類が悪いんだろう。
0842デフォルトの名無しさん
2008/08/05(火) 15:15:59このスレ開いただけでも望みはある!
0843デフォルトの名無しさん
2008/08/05(火) 18:04:550844デフォルトの名無しさん
2008/08/05(火) 19:53:06メモリをイメージする訓練も大切だが、
もっと抽象的に捉える訓練も忘れないで欲しいな。
0845デフォルトの名無しさん
2008/08/05(火) 20:05:180846デフォルトの名無しさん
2008/08/05(火) 21:13:44真の文法を書いてる本は稀少なのかね。
0847デフォルトの名無しさん
2008/08/05(火) 21:27:48真の文法を書いている本でも、いでおしんくらてっぃくなところは
はしょっているか、読み取れないようにしてるのが多いと思う。
実際、俺なんか、
int typedef integer;
なんて構文が許されるなどとはイソターネットで初めて知った。
0848デフォルトの名無しさん
2008/08/05(火) 21:44:040849デフォルトの名無しさん
2008/08/05(火) 21:47:550850デフォルトの名無しさん
2008/08/05(火) 22:11:34真の文法をサポートする本とはLinuxのことである。
Linux以外は紛い物である。
0851デフォルトの名無しさん
2008/08/06(水) 00:58:33いや、意味が理解できないなら別にいいんだ。
>>839-841
C/C++ に毒されすぎ (w
文字列と文字の配列が互換の言語はあまり多くないから、
"abcd"[0] を >>834 が奇異に感じるのも無理は無いよ。
0852デフォルトの名無しさん
2008/08/06(水) 00:59:350853デフォルトの名無しさん
2008/08/06(水) 01:15:22さすがに理解できました。
>多分、そういうコードを今まで見たことが無い、見慣れない、ってだけだろう。
そうですね。はじめてみました。
なんかすっきりしました。
皆さんありがとうございました。
なんかビット演算って難しそうですけど、面白そうですね。
私も、最近処理速度を意識したコードを書く機会があるので
色々参考にします。
(クロックが25KHzなので、処理速度を意識しないといけないんですよ)
0854デフォルトの名無しさん
2008/08/06(水) 01:31:440855デフォルトの名無しさん
2008/08/06(水) 09:28:350856デフォルトの名無しさん
2008/08/06(水) 21:19:11そうなんですよ。1サイクル40usなので、ビット操作(ビットクリアやビットセット)で
7サイクル取られるので、7*40=280us=0.28msもかかるんですよね・・・
0857デフォルトの名無しさん
2008/08/06(水) 21:30:37最近は組み込みの分野でもJAVAだったりするが、まだまだCの出番はあるってことか。
0858デフォルトの名無しさん
2008/08/06(水) 22:00:420859デフォルトの名無しさん
2008/08/06(水) 22:06:20> まだまだCの出番はあるってことか。
て言うか、アセンブラの出番だと思うけど。
0860デフォルトの名無しさん
2008/08/06(水) 22:17:37如何にCで効率の良いコードを書くか。
クロックを遅くしているのは消費電流の低減のためです。
普段は32MHzで動作しますよ。
0861デフォルトの名無しさん
2008/08/09(土) 17:23:46ちょっと遅くなったが、求め方が解った。
今回は2^1〜2^9だからちょっと変則的なんだが、概念としてはM系列の応用みたい。
なるほどねー。
http://slashdot.jp/~Tellur52/journal/448479
0862デフォルトの名無しさん
2008/08/09(土) 17:25:18お前ここに糞スラのURL張るの禁止されていること
しらんのか?
0863デフォルトの名無しさん
2008/08/09(土) 17:27:12え?あっちから拒絶してんの?
0864デフォルトの名無しさん
2008/08/09(土) 17:27:38スマンかった。忘れて。
0865861
2008/08/09(土) 17:31:07あっちも出入りしているけど、そういうことはないと思う。
ここの板ローカルのルールなのかね?
ここも長年見ているが、あまり聞いたことないけど。
0866デフォルトの名無しさん
2008/08/09(土) 18:01:210867デフォルトの名無しさん
2008/08/09(土) 18:40:270868デフォルトの名無しさん
2008/08/10(日) 02:54:03p=3の場合のM系列は例えばこう。
0011101
↓ (周期2^3-1=7で同じパターンの繰り返し)
001110100111010011101...
上の桁から3ビットを切り出すと、
001 (1)
_011 (3)
__111 (7)
___110 (6)
____101 (5)
_____010 (2)
______100 (4)
1〜7まで全部出るだろ。これに000だけ追加すればおk。
これだけだと順番がバラバラなので、テーブルと組み合わせる。
↓この文字列リテラルの部分な。
"xxxxxxx"[(ハッシュ計算式)]
すると、>>762-763になりますよ、と。ビット溢れによるマスクなども組み合わせているが。
0869デフォルトの名無しさん
2008/08/10(日) 03:11:08最長系列(M系列)が得られるんだが,
このタップが整数論の方の原始多項式から求められるというのは覚えてる
0870デフォルトの名無しさん
2008/08/10(日) 16:08:47素人が下手にCで最速コード書くと後で自分で読めないから、最初からアセンブリでやったほうがいいと思う
マクロが使えれば読みやすくなるのも事実だしな
MASMだと、アセンブリの癖にIFだのELSEだの使える。マクロがなければCでプリアセンブラを書けばいいし
0872デフォルトの名無しさん
2008/08/10(日) 17:38:030873デフォルトの名無しさん
2008/08/10(日) 17:55:59移植性や保守性を犠牲にしてでも高速化しようってのが趣旨なのに。
0874デフォルトの名無しさん
2008/08/10(日) 18:16:420875デフォルトの名無しさん
2008/08/10(日) 18:25:560876デフォルトの名無しさん
2008/08/10(日) 18:31:54ちょっと暴走して勃起が止まりません
リセットできないどうしよう
0877デフォルトの名無しさん
2008/08/10(日) 18:35:440878デフォルトの名無しさん
2008/08/10(日) 19:02:200879デフォルトの名無しさん
2008/08/10(日) 19:20:290880デフォルトの名無しさん
2008/08/10(日) 19:20:34そりゃビット演算すれば多少は移植性が犠牲になるだろうけど、
それだけならぜんぜん問題にはならない。
所詮フラグなんて1本しかないんだからな。
ただまあ、
大きさはいろいろだから互換性がない場合も確かにある。
0881デフォルトの名無しさん
2008/08/26(火) 15:29:02〒 ! + 。 + 。 * 。
+ 。 | |
* + / / イヤッッホォォォオオォオウ!
∧_∧ / /
(´∀` / / + 。 + 。 * 。
,- f
/ ュヘ | * + 。 + 。 +
〈_} ) |
/ ! + 。 + + *
./ ,ヘ | このスレッドは880を超えました。
ガタン ||| j / | | ||| 次レスも…BITクオリティ!!
―――――――――――― http://pc8.2ch.net/tech/
ああ暇だ
0882デフォルトの名無しさん
2008/08/27(水) 20:01:38http://science6.2ch.net/test/read.cgi/math/1209732803/
の427に問題を投稿したんで、暇ならチャレンジしておくれ。
0883デフォルトの名無しさん
2008/08/27(水) 20:36:010884デフォルトの名無しさん
2008/09/04(木) 14:51:58ここまでくると、なにがなにやら
0885デフォルトの名無しさん
2008/09/04(木) 15:15:420886デフォルトの名無しさん
2008/09/13(土) 20:24:380887デフォルトの名無しさん
2008/09/14(日) 13:55:190888デフォルトの名無しさん
2008/09/16(火) 23:19:160889デフォルトの名無しさん
2008/09/17(水) 01:25:58888
0890デフォルトの名無しさん
2008/09/17(水) 16:29:380891デフォルトの名無しさん
2008/09/17(水) 16:31:310892デフォルトの名無しさん
2008/09/17(水) 17:12:100893デフォルトの名無しさん
2008/09/17(水) 19:24:05その表記、キモすぎるw
0894デフォルトの名無しさん
2008/09/27(土) 11:01:16例えば、2の補数で表される4bitの値を8bitに変換する場合、
正の値: 0001 -> 0000 0001 # 最上位bitが0なら上位bitに0000を補う
負の値: 1110 -> 1111 1110 # 最上位bitが1なら上位bitに1111を補う
bit8 = (bit4 & 0x8) ? (bit4 | 0xF0) : bit4;
逆の変換は、
正の値: 0000 0001 -> 0001 # 上位4bitを削除
負の値: 1111 1110 -> 1110 # 上位4bitを削除
bit4 = bit8 & 0xF;
という考え方で合ってます?
0895デフォルトの名無しさん
2008/09/27(土) 11:13:010896デフォルトの名無しさん
2008/09/27(土) 11:29:260897,,・´∀`・,,)っ-○◎●
2008/09/27(土) 12:16:50ARMならプレディケートに展開されるのでそれで十分速いんだが
欲をいえばこっちのほうが命令数とかレジスタ節約できるかもしれないね。
bit8 = bit4 | (bit4 & 0x8) ? 0xF0 : 0;
また、比較命令はall 1 か all 0のビットマスクを生成するタイプのCPUなら、
ビットマスクと0xF0との論理積をとるだけで加算する値を取得できる。
しかし、2項選択は多くのCPU分岐命令に一般的には遅い。
シフトが遅くないならこっちを試してもいい
bit8 = (signed char)bit4 << 4 >> 4;
現実には多くの32ビットCPUはレジスタサイズ未満のビット演算は遅いのでこっちのほうがいいかも
bit8 = (signed char)(((signed int)bit4 << 28) >> 28);
要はネイティブで算術シフト命令のできる最小単位ならなんでもいい。
同じロジックでbit16でもbit32でも展開できる。
0898,,・´∀`・,,)っ-○◎●
2008/09/27(土) 12:31:00日本語しゃべれ俺
0899デフォルトの名無しさん
2008/09/27(土) 13:06:59バグってるぞ。
0900,,・´∀`・,,)っ-○◎●
2008/09/27(土) 13:13:06これでいいのか?
0901894
2008/09/27(土) 13:35:56CPUは普通のPCのIntel x86系です。
0902,,・´∀`・,,)っ-○◎●
2008/09/27(土) 13:49:08bit4 = ecx
bit8 = eax
と仮定して
mov eax, ecx
sal eax, 28
sar eax, 28
and eax, 0xFF
たった4命令で済む。bit4を破壊していいなら3命令。
0903デフォルトの名無しさん
2008/09/27(土) 19:47:32ちがうだろ
算術シフトか論理シフトかはコンパイラ依存
0904デフォルトの名無しさん
2008/09/27(土) 19:50:090905,,・´∀`・,,)っ-○◎●
2008/09/27(土) 22:02:58//でコメントにならないコンパイラ並みには非互換問題あるのかな?
ローテートくらいまではC/C++標準仕様に入れておいて欲しいものだ
0906デフォルトの名無しさん
2008/09/27(土) 22:19:030907デフォルトの名無しさん
2008/09/27(土) 22:26:53> 算術シフトか論理シフトかはコンパイラ依存
負数の右シフトの動作のことを言ってるのか?
>> 2の補数で表される4bitの値を8bitに変換する場合
という条件下なら >>894 の内容に誤りはないと思うが。
そもそも、>>894 のレスにシフトのコードなんてないし。
# レスアンカーが >>897 なら同意するけど、あまり
# 触らない方がいいと思う。
0908,,・´∀`・,,)っ-○◎●
2008/09/27(土) 22:33:18static const signed char table[] = { 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1 };
bit8 = table[bit4 & 15];
0909デフォルトの名無しさん
2008/09/27(土) 22:33:410910デフォルトの名無しさん
2008/09/28(日) 12:15:36算術シフトもちょっと……という場合にはこっちがいいのでは。
bit8 = -(bit4 & 0x8) | bit4
0911デフォルトの名無しさん
2008/09/28(日) 12:29:09等幅じゃないと見にくいけど分かってもらえるかな。
src temp dst
????mxyz 00000000 00000000
????mxyz 0000m000 00000000 # temp = src & 0x8
????mxyz 0000m000 mmmmm000 # dst -= temp
????mxyz 0000m000 mmmmmxyz # dst |= src
0912,,・´∀`・,,)っ-○◎●
2008/09/28(日) 12:34:50SSSE3のpshufbやAltiVecのvpermで16並列化もできるし。
0913,,・´∀`・,,)っ-○◎●
2008/10/02(木) 00:50:06x86で4命令だな。
mov eax, ecx
and eax, 0x08
neg eax
or eax, ecx
ちなみに>>902の方法はこれなら3命令。
mov al, cl
sal al, 4
sar, al 4
ただ、とてつもなくパーシャルレジスタストールの臭いがするぜ
0914デフォルトの名無しさん
2008/10/11(土) 16:18:31今は、8ビットローテートの場合は
(val << num) | (val >> (8-num) )
って書いてるけど、アセンブラ見てもまんまシフトとORで作られるんだよな
最後の手段でインラインアセンブラ使ってるけど、誰かCでいい書き方知ってたら教えてくれ
0915デフォルトの名無しさん
2008/10/11(土) 16:23:260916デフォルトの名無しさん
2008/10/11(土) 16:30:52unsigned foo(unsigned x, int n) {
return (x << n) | (x >> (32 - n));
}
で↓になったよ
_foo:
movl 4(%esp), %eax
movl 8(%esp), %ecx
roll %cl, %eax
ret
8ビットは無理だた
0917デフォルトの名無しさん
2008/10/11(土) 16:48:330918914
2008/10/11(土) 16:51:22ちなみにCPUはARM、コンパイラはARM製のコンパイラです
速度に関しては何ビットローテートしても1クロックで済む、RISC万歳
0919デフォルトの名無しさん
2008/10/11(土) 17:56:35インラインアセンブラで書いたものを、インライン展開できるようにしておくのはダメなの?
インラインの関数呼び出しでは不満?
演算子でやりたいなら、演算子をインライン展開できるように定義すればいいだけだと思うが。
0920,,・´∀`・,,)っ-○◎●
2008/10/12(日) 14:47:040921デフォルトの名無しさん
2008/10/13(月) 21:04:47コンパイラが認識する組込関数にすれば十分だよ。
0922デフォルトの名無しさん
2008/10/19(日) 21:43:35@>
<@
0923デフォルトの名無しさん
2008/10/19(日) 21:49:25<reg<
0924デフォルトの名無しさん
2008/10/19(日) 22:01:01��
0925デフォルトの名無しさん
2008/10/20(月) 01:05:00_lrotl
0926デフォルトの名無しさん
2008/10/20(月) 15:43:41<|
0927デフォルトの名無しさん
2008/10/20(月) 22:06:50指輪物語?
>>926
シュレディンガー音頭?
0928デフォルトの名無しさん
2008/10/21(火) 08:56:43ばかでしょ
0929デフォルトの名無しさん
2008/10/21(火) 23:59:570930デフォルトの名無しさん
2008/10/22(水) 00:38:04tlotr
0931デフォルトの名無しさん
2008/10/22(水) 00:46:100932デフォルトの名無しさん
2008/10/22(水) 00:53:090933デフォルトの名無しさん
2008/10/22(水) 00:56:14tlotr
ググれば一目瞭然。
0934デフォルトの名無しさん
2008/10/22(水) 04:08:260935デフォルトの名無しさん
2008/10/22(水) 08:55:550936デフォルトの名無しさん
2008/10/22(水) 12:18:22つまり、オフィシャルサイトは間違っていると。
0937デフォルトの名無しさん
2008/10/22(水) 12:34:52Lordが正しい。
>>936
「the」がないのは、ドメイン取得の問題じゃないかな。
0938デフォルトの名無しさん
2008/10/22(水) 16:44:03man gawk を見ると
lshift, rshift って内部関数が実装されているんだな。
0939デフォルトの名無しさん
2008/10/22(水) 21:50:42指輪とはあんまり関係ない。
0940デフォルトの名無しさん
2008/10/22(水) 21:59:170941,,・´∀`・,,)っ-○◎○
2008/10/23(木) 01:44:47>>940それ第1章の副題
0942デフォルトの名無しさん
2008/10/23(木) 08:38:48何…だと……?
0943デフォルトの名無しさん
2008/10/25(土) 00:00:41lotr の検索結果 約 9,330,000 件中 1 - 10 件目 (0.15 秒)
tlotr の検索結果 約 69,400 件中 1 - 10 件目 (0.17 秒)
一体何が一目瞭然なんだか。
>>937
> 「the」がないのは、ドメイン取得の問題じゃないかな。
レスするなら、URL だけじゃなくてちゃんとページ見ろよ。
省略形で定冠詞を省略するのはごく普通。
2個あるうちの片っぽだけというのはちょっと違和感あるけど。
0944デフォルトの名無しさん
2008/10/25(土) 01:12:27【指輪】ビット演算 0x03【物語】
0945デフォルトの名無しさん
2008/10/25(土) 01:13:310946デフォルトの名無しさん
2008/10/25(土) 01:17:200947デフォルトの名無しさん
2008/10/25(土) 17:26:25これはコラだね、俺は騙されんよ。
0948デフォルトの名無しさん
2008/10/25(土) 18:44:44>>945
0949デフォルトの名無しさん
2008/10/25(土) 18:53:14>947
0950デフォルトの名無しさん
2008/10/25(土) 21:52:57>>9
0951デフォルトの名無しさん
2008/10/26(日) 20:50:31それは省略形であって正式ではない。
テレビジョンよりテレビの方がヒットするのは当たり前だろ。アホか。
0952デフォルトの名無しさん
2008/10/26(日) 21:00:55111111011
↓
111110111
↓
111101111
↓
111011111
こう言う感じで
0953デフォルトの名無しさん
2008/10/26(日) 21:02:22a | 1
0954デフォルトの名無しさん
2008/10/26(日) 21:06:31速レスサントス
0955,,・´∀`・,,)っ-●◎○
2008/10/26(日) 21:10:291のほうを立てて
00000100
↓
00001000
↓
00010000
↓
00100000
参照するときに反転すればいいと考えるんだ
0956デフォルトの名無しさん
2008/10/26(日) 23:24:330957デフォルトの名無しさん
2008/10/26(日) 23:41:34> それは省略形であって正式ではない。
一体何を言ってるんだ?
> テレビジョンよりテレビの方がヒットするのは当たり前だろ。アホか。
アホはお前だよ、単語の区切ぐらい見てるだろ。
yaho の検索結果 約 2,580,000 件中 1 - 10 件目 (0.06 秒)
yahoo の検索結果 約 2,330,000,000 件中 1 - 10 件目 (0.08 秒)
そもそも、どうやって「ググれば一目瞭然」なのか >>933 に聞けよ、クズ。
0958デフォルトの名無しさん
2008/10/26(日) 23:54:28もうどうでもいいよ
0959デフォルトの名無しさん
2008/10/27(月) 00:08:360960デフォルトの名無しさん
2008/10/29(水) 11:21:19あの文章に対してこんな事言ってるようじゃ
やはり>>957が真のアホと言わざるを得ない
0961デフォルトの名無しさん
2008/10/29(水) 12:11:340962デフォルトの名無しさん
2008/10/29(水) 22:03:47「r',. 、
d ´c`/ ちくしょう・・・
i ' ∋
ぉち 彡 ,.-,ニユ、
ぉ く .三 { ,.= r、
|し 三 (6' r',ニ7
|ょ 三. | !| { {
|お 三. | ミ‐ニ)
! ! ぉ ミ ! {
0963デフォルトの名無しさん
2008/10/29(水) 22:42:12>> テレビジョンよりテレビの方がヒットするのは当たり前だろ。アホか。
いや〜、賢いねぇ。(w
0964デフォルトの名無しさん
2008/11/02(日) 13:18:15だから、>>763の方法で計算できるのは、aに近い整数値でしかない。
それに、渡さされる2^aの値が整数かどうかも記載されていないな。
ビット演算だから常に整数という誤認があったかもしれん。
まあ、小数点以下の計算も整数演算の延長でしかないから問題ないけど。
0965デフォルトの名無しさん
2008/11/05(水) 11:24:39int fill(int n){
n |= n>>1;
n |= n>>2;
n |= n>>4;
n |= n>>8
n |= n>>16;
return n;
}
てのを作ってみたんだが、まだ速くできるかな?てか、この処理に名前ってある?
0966デフォルトの名無しさん
2008/11/05(水) 14:28:15アセンブラ使っていいなら2命令で終わり。
0967デフォルトの名無しさん
2008/11/05(水) 18:04:270968デフォルトの名無しさん
2008/11/05(水) 18:38:44int fill(int n) {
return n ? (~0u >> __builtin_clz(n)) : 0;
}
0969デフォルトの名無しさん
2008/11/05(水) 20:23:000970デフォルトの名無しさん
2008/11/05(水) 21:24:260971デフォルトの名無しさん
2008/11/05(水) 21:55:59n=0の時上手くいかないだろうけど。
0972デフォルトの名無しさん
2008/11/05(水) 22:00:560973デフォルトの名無しさん
2008/11/05(水) 22:04:210974デフォルトの名無しさん
2008/11/05(水) 22:26:370975デフォルトの名無しさん
2008/11/05(水) 22:58:48環境依存しないようにするなら、unsignedをつけて
>>971にandをかませば良いと思う。
unsigned int fill(unsigned int n) {
unsigned int a;
a = n & 0x80000000ul;
return a & (a - (a >> 31))
}
ただし、MSBが1でないときに何を返したいかによってはダメだけど
0976デフォルトの名無しさん
2008/11/05(水) 23:01:15違った
return a | (a-(a >> 31));ね
0977デフォルトの名無しさん
2008/11/05(水) 23:32:000978デフォルトの名無しさん
2008/11/06(木) 00:25:46顔を洗って出直してこい。
0979デフォルトの名無しさん
2008/11/06(木) 08:48:03ほんとにそうだな。
>>976のようにスペースを入れるとよい。
0980デフォルトの名無しさん
2008/11/06(木) 22:03:20>>976
で計算すると
0x00008080
に、
>>965
で計算すると
0x0000ffff
になる。
0981デフォルトの名無しさん
2008/11/06(木) 23:12:08>>980
理解した。出直す。
レス数が950を超えています。1000を超えると書き込みができなくなります。