[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 05/09 20:05 / Filesize : 206 KB / Number-of Response : 960
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【高速化】ビット演算 0x02



1 名前:デフォルトの名無しさん [2006/09/16(土) 09:46:26 ]
前スレ
ビット演算
pc8.2ch.net/test/read.cgi/tech/1123918075/


関連スレ
アセンブラ… (゜□゜) ↑アッー!↓
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

201 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 15:08:21 ]
あまり適当な番号には見えない件について

202 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 16:12:03 ]
0xC8

203 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 16:43:42 ]
丁度256円になります。

204 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 16:47:10 ]
ポイントはお付きしますか?

205 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 16:50:33 ]
いいえ、彼はペンです。

206 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 02:12:41 ]
char v;
if(v){ ..... }

vのビット列が [10000000] と [00000001]
ではやっぱり前者の方が早いんだろうか

207 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 02:21:08 ]
最適化や前後のループや分岐予測によるだろ…常識的に考えて…

208 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 02:37:55 ]
嫌な答え方だな

209 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 03:18:03 ]
感じないわ。



210 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 03:39:36 ]
痛くないわ。


211 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 11:01:09 ]
五寸釘はイヤだろ・・・・常考

212 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 11:21:15 ]
ごっすんごっすん五寸釘ー

213 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 12:16:52 ]
そっちかよクソ

214 名前:デフォルトの名無しさん mailto:sage [2007/05/06(日) 17:55:55 ]
あいーん


215 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 21:23:54 ]
効率的では無いけど少々トリッキーなJavaのコード。数列の解説は面倒なので略。

float[] 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");
}

216 名前:215の出力結果(1/2) mailto:sage [2007/05/14(月) 21:26:12 ]
+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,
+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,

217 名前:215の出力結果(2/2) mailto:sage [2007/05/14(月) 21:27:16 ]
+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,
+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,

218 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 21:53:43 ]
誰かエスパーしてくれ

219 名前:デフォルトの名無しさん mailto:sage [2007/05/14(月) 23:11:47 ]
新手の荒らしだろ、スルーよろ。



220 名前:デフォルトの名無しさん mailto:sage [2007/05/15(火) 00:22:46 ]
k = (((i>>>2)^(i>>>1)^i)&1)*12;

k = ((i>>>2)&4)*12;
と等価じゃない?

221 名前:デフォルトの名無しさん mailto:sage [2007/05/15(火) 00:24:00 ]
k = (((i>>>2)^(i>>>1)^i)&1)*12;

k = ((i>>>2)&1)*12;
と等価


222 名前:デフォルトの名無しさん mailto:sage [2007/05/15(火) 00:25:45 ]
おいおい、不等号3つって……

223 名前:デフォルトの名無しさん mailto:sage [2007/05/15(火) 00:56:43 ]
System.out.printfって何だよ
オブジェクト指向すげえよ

224 名前:デフォルトの名無しさん mailto:sage [2007/05/15(火) 02:01:14 ]
>>>220-221
^は排他的論理和、>>>は符号無し右シフト、&は論理積なので、
k=(((i>>>2)^(i>>>1)^i)&1)*12はi=1,2,4,7の時にk=12、i=0,3,5,6の時にk=0となる。
全然等価じゃねーぞ。

225 名前:215 mailto:sage [2007/05/15(火) 03:58:02 ]
エスパー困難なコードですが、一番意図の分かりにくい部分だけ解説。

k = (((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:行・列ともに逆順

226 名前:デフォルトの名無しさん mailto:sage [2007/05/15(火) 04:07:12 ]
そこまで式が込み入ってたら、テーブルの方が速くないかな。
まあ、環境によるとは思うが。

227 名前:デフォルトの名無しさん [2007/05/20(日) 08:13:37 ]
あげ

228 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 07:41:36 ]
ある変数の中でビットが必ず一つだけ立っているとき
そのビットの位置(左右どちらからでもよい)を求めたいのですが
↓のNTZやNLZを求めるアルゴリズムを使うのよりも高速にできませんか?
www.nminoru.jp/~nminoru/programming/bitcount.html
立っているビットの数が一つという条件があるので
何か工夫できないか考えたんですけど思いつきません。

229 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:06:11 ]
どっかで聞いたような質問だな・・・



230 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:07:19 ]
memcpyよりも高速にコピーできる高速memcpyを作りたいのですが
何か参考になる方法ってありますか?

231 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:18:56 ]
>>230
memcpyより高速な手法が存在するとしたら、世の中のmemcpyはその高速
な手法を使うんじゃない?


232 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:24:56 ]
>>230
ビット単位で転送するという話でもない限り、スレ違い。

233 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:26:58 ]
>>231
いいえ。

234 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:31:37 ]
前スレのログってどこかにある?

235 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:35:42 ]
あ、あったあった。
p2.chbox.jp/read.php?host=pc8.2ch.net&bbs=tech&key=1123918075&ls=all
ここの377に似たような質問があるね。

236 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 08:39:30 ]
>>228
ビット位置を持って回ることを検討したか?

>>230
つ [ゼロコピー]

237 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 09:05:14 ]
ビット位置を持って回るのは難しいと思いました。
ビットはこんな風に複数のビットが立ってる変数から取り出してます。
UInt32 bits;
...
while(bits)
{
UInt32 bit = bits&(-bits);
UInt32 bit_position = get_bit_position(bit);
...
}
で、このget_bit_position()の部分を作りたいのですが・・

238 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 09:12:52 ]
ちょっと>>235を読んできます

239 名前:デフォルトの名無しさん mailto:sage [2007/05/22(火) 10:16:01 ]
とりあえず>>235の430でやってみます。
みなさんありがとうございました。



240 名前:デフォルトの名無しさん [2007/05/23(水) 15:19:02 ]
24xx32〜24xx512 までのシリアルEE-PROMというのは
pageというのを持っていてページサイズ内なら一度に書き込みが出来ます
ページサイズは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) ) が最初に書く領域 

というふうに考えたのだけど、ループが格好良く書けないの。

241 名前:デフォルトの名無しさん mailto:sage [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 );


242 名前:デフォルトの名無しさん mailto:sage [2007/05/24(木) 05:19:07 ]
格好良いかどうかは主観だという良い例。

243 名前:デフォルトの名無しさん mailto:sage [2007/05/25(金) 17:20:07 ]
>>241
普通に書くとこんな感じ?

    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 を指定されると大変なことになりそうだな。


244 名前:デフォルトの名無しさん mailto:sage [2007/05/27(日) 15:33:15 ]
汚いJavaコードコンテストの会場はこちらですか?

245 名前:デフォルトの名無しさん mailto:sage [2007/05/27(日) 15:35:13 ]
いいえ、ここはJavaを知らない244が居るスレです。

246 名前:デフォルトの名無しさん mailto:sage [2007/05/27(日) 22:25:32 ]
面白くない 失せろ

247 名前:デフォルトの名無しさん [2007/05/27(日) 23:15:48 ]
エンディアンの変換を共用体でやるのってどうやるんですか?

248 名前:デフォルトの名無しさん mailto:sage [2007/05/27(日) 23:26:39 ]
バイトオーダーは詳しくないが
int, 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 にはならないのでは?

249 名前:・∀・)っ-○◎● mailto:sage [2007/05/27(日) 23:31:17 ]
こうですかわかりません><

typedef 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;




250 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 00:21:29 ]
ヤツはダンゴさんじゃない

251 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 00:52:56 ]
共用体って、本当はそういう風に使っちゃダメなんだよな。
規格違反。
まあ、そう使えないコンパイラはないと思うけど。

252 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 08:09:58 ]
おいおい共用体をそういう風に使わずにほかにどんな用途があるって言うんだアホかw

253 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 10:29:21 ]
使ってはいけない理由があるからそう決められているんだろ。
その理由が皆目検討つかないが。

254 名前:240 mailto:sage [2007/05/28(月) 10:38:09 ]
>>243
ありがとう。参考になった。
でも、そのままだと最後の書き込みサイズが正しくなかったよ。

255 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 15:48:22 ]
>>252,>>253
共用体のメンバのうち T 型の a というメンバに値が格納されているときは
U(!= T) 型の b というメンバの値は T 型の a に依存し、U 型の値としては
不正と見なされるため b を通してのアクセスは未定義の動作となる。


ではなぜ共用体が存在するのかというと、おそらく原始的なポリモーフィズムの
実現の為。

ある変数が複数通りの型(ここでは T と U とする)の値を受け入れる可能性が
あるとき、構造体のような、型の異なる複数の変数を用意するのは非効率のため
単一の変数で複数の型を扱える共用体を使う。

もっとも、C++では T 型と U 型の基本クラス V 型を定義して、V 型の参照として
T 型にも U 型にも(もちろん V 型にも)正規にアクセスできるので、共用体は
不要になってしまった(のだろう、たぶん)。

256 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 17:15:17 ]
共用体はこういうことのためにある。

enum 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);
}

257 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:18:41 ]
>>255
> もっとも、C++では T 型と U 型の基本クラス V 型を定義して、V 型の参照として
> T 型にも U 型にも(もちろん V 型にも)正規にアクセスできるので、共用体は
> 不要になってしまった(のだろう、たぶん)。

不要になってないだろ。

基本クラス云々で各種のデータを扱う処理は正規にできるようになったけど、
複数の型を同一の領域に割り付けるのは union でないとできない。

まあ、そんな機会はめったとないが。

258 名前:デフォルトの名無しさん [2007/05/28(月) 22:22:43 ]
普通わざわざそんな面倒なことしないと思いますけどねw
それで何の御利益があると思って書いてるんだろうか?
不思議な発想だとしか言いようがない

っていうか、それ多態じゃなくて多重定義でしょ?w

259 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:29:27 ]




260 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:31:52 ]
258は>>255-256宛てね

261 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:35:30 ]
型がクラスだったりする可能性を考えると
共用体よりplacement newのほうが良いと思う。

262 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:36:54 ]
バリアント型とか知らないのかな。
そして、それが内部的にどうなってるかとか、
そこでのコスト意識とかに至っては、全く考えた事ないんだろうね。

263 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:38:44 ]
>>261
共用体に入れられるのはそもそも POD 型だけだが、
ポインタで保持しておくことなら可能だな。

264 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:54:29 ]
>>262
> バリアント型とか知らないのかな。

C言語でそんなもん使う機会があまりないこととか知らないのかな。(w

265 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 22:59:44 ]
いや、煽り抜きでそういう発想はちょっとないよね。

266 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:06:16 ]
Cだとバリアント型はにっくきCOMの象徴のひとつだからトラウマが・・・w

267 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:11:53 ]
皆がどのレスについてレスしてるのか分からなくなってきた。
つーかビット演算スレでなぜ共用体…。

「そういう発想」というのは共用体をvariantとして使う発想ということかしら。

268 名前:webmaster@気まぐれアナスイ mailto:192.168.0.1 [2007/05/28(月) 23:11:54 ]
   { >>>>>>>>985 }
    ζ
     !(+Φ_Φ)つ√ζ
    +⊂. + 〆∂   {Ж}
    "〆∂∂
   〆〆
  .:"


269 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:15:15 ]
コピペ君って馬鹿だな、まで読んだ。



270 名前:デフォルトの名無しさん [2007/05/28(月) 23:38:38 ]
>>256
でも共用体って記述した順番にメモリに保存されるかについて
仕様では未定義ですよね

271 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:40:46 ]
>>270
当たり前だろ。

つか struct の仕様と混同してないか?

272 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:43:42 ]
>>270
これはひどい

273 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:45:43 ]
コンパイラコンパイラ触ってるなら、
このくらい常識だろ?

274 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:46:54 ]
という批判と、このスレでの質問だという事を考えると、>>249 は

typedef 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];

みたいなのが希望って事か?

275 名前:デフォルトの名無しさん mailto:sage [2007/05/28(月) 23:49:33 ]
それは二重に規格違反してて、
おかしくなるコンパイラもあるらしいよ。
俺はそういうの見た事無いけど。

276 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 00:13:33 ]
おかしくなるコンパイラがあるのではなく、動作が保証されないということ。
そういうコンパイラが現実にあるのかと言われても、んなこと知らん。
だが、顧客に「正常に動作することが保証されている」プログラムを提供するためには
仕様上未定義とされる書き方をしてはいけないし、意識せずしてしまったらバグとして扱われて然り。

277 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 00:20:53 ]
参考までに>>274の規格違反している点を簡単に指摘してください

278 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 00:32:45 ]
規格違反していても、多分 >>249 がおかしくなる処理系はないんじゃね?
逆に、規格通り書いてもおかしくなることもある。
規格違反はそれはそれで重要だけど、
実際の処理系でどうなのかという方が時に重要な事もある。
ま、コメントとか残しておいて、
移植時にすぐ検索できるようにしておくべきではあるが。

279 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 00:44:32 ]
>>277
共用体の pW メンバに代入した場合、
pW の値しか正当性が保証されない。
そのため、pW に代入したすぐ後に pB を参照したとき、
規格ではその動作を保証しない。

uint32_t * と uint8_t * のアドレス表現が等しいという保証は無い。
この間のキャストで何らかの変換作業が生じる場合には、
このコードは正しく動かない。

そもそもアドレス演算は、配列要素へのポインタでしか保証されない
(配列風の参照では p[4] と *(p + 4) は等価で、
 ここには p + 4 というアドレス演算が生じる)。
ここが原因で >>274 のようなことをすると
おかしくなる処理系があるという風に聞いている。
(「ハッカーのたしなみ」 の 87 ページを参照)



280 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 01:08:03 ]
ハッカーのたしなみ に一致する日本語のページ 約 104 件
ハッカーのたのしみ に一致する日本語のページ 約 26,800 件

281 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 01:15:26 ]
すまんよ。まちがえた。

282 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 10:36:39 ]
そもそもCの言語仕様で「未定義」な理由は、最初のバイトが最上位か最下位かはエンディアン依存だから。
逆にいうとハードに強く依存する標準仕様はあってはならない。

もちろん環境が特定できる場合なら、エンディアンの違いを理解して使うぶんにはまったく問題ない。
むしろ同一アーキテクチャでならコンパイラのABIレベルではこういう部分も互換性が保障されてないと駄目。
そもそもエンディアンなんて標準仕様外のものを扱うのに、標準仕様を持ち出すほうがおかしいと思うがね
構造体などのデータアラインメントやABIの互換性は言語の規格じゃなくて
各CPUやOSのメーカー、コンパイラメーカーなど同士の取り決めで決まる。
つーか、暗黙の共通仕様や独自仕様にたよらないとTCP/IPすら扱えないぜ。

283 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 10:52:02 ]
構造体のアラインメントはC仕様では未定義だが、アラインメント不整合だと例外を起こすアーキもある。
データレイアウトを実装者で取り決める独自仕様が認められないなら、Cは危険な言語だな逆にいえば。

「仕様では未定義」は逆にいえば実装では各環境のABIに従ってきめていいということ。


284 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 11:17:39 ]
>>282-283
仕様上未定義を「未定義の動作」と混同していないか。
Cは移植性を高めるため、特定の環境に依存するような仕様はほとんど盛り込まれておらず
よって指摘の通り構造体のメモリ上でのレイアウトも定義されていない。

だが、メンバに正しくアクセスできることは保証されている。

285 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 11:25:40 ]
実は未定義ではなく実装依存という罠

286 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 11:38:48 ]
エンディアンの変換はほぼ間違いなくできるがリトルからビッグかビッグからリトルかはエンディアン依存ってことだろ。

逆に>>349が意図しない動きをするコード吐くコンパイラって存在するなら教えてほしい。
変態のCellですら>>349が正しく動くことはABIレベルで保証されてる。
各型のレイアウトを厳密に定義してるからな。

287 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 11:43:14 ]
共用体で  ビットフィールド を使えば、マシになるかい?

288 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 12:21:19 ]
>>286
>>276
そして話題はループする。

ABIはCの言語仕様における実装依存の箇所を定めて厳密化するものなので
たとえABIの隙をかいくぐって自分の予期した挙動をさせることができたとしても
それは立派な規格違反。

あと、もし>>282さんと同一人物なら
>そもそもCの言語仕様で「未定義」な理由は、最初のバイトが最上位か最下位かはエンディアン依存だから。
これのソースを頼む。探しているんだが、見つからない(汗

289 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 12:27:18 ]
規格にないものを扱うのに規格内のルールを持ち出す馬鹿。
windows.hを使うのも規格違反だとか言い出しそうだな



290 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 12:34:19 ]
厳密にはそうだな。ハンドルをポインタ型とかメチャクチャしたMSは糞。
ちなみに、規格にないものを付け加えるのではなく、規格に抜けているを補うのがABI。
本来は規格に矛盾しないABIを定めなければならない。

ところでここはビット演算についてかたるスレなのか?

291 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 12:56:10 ]
ミドルエンディアンのこともたまには思い出してやってください

292 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 13:13:17 ]
GUIがなくてstdioで画面入出力するようなアプリのほうが品質低いと見なすがなうちの顧客は。

「定義するな」なら違反になるが単に未定義のものに一定の動作保証をするだけなら違反じゃない。
何のために#pragmaが規格にあると思ってる。
処理系依存の拡張を、やっていいよと保証すらしてるのが規格だ。

ちなみにunion使った型変換はWindowsでは日常茶飯事だな。ULONG_INTEGERとか。
ここの住人がよく使うであろうMMXやSSEなんかはC用APIなんか、まさに共用体を使った型変換のオンパレード。
それでもパフォーマンスを求める客の「信頼」を得るためにすすんで使うものだ。

ANSI/ISO規格が絶対的に信頼されてて規格外のものは信頼されてないなんて独善的な言い分にすぎん。
getsみたいな危険な関数が野放しにされてるのはなんだね。
極論、信頼性の確保という面ではVC2005のセキュアCRT関数のほうが標準関数よりまとも。

ちなみにポインタをHANDLEという型にtypedefできるのは規定の動作。なんら問題ない。

293 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 13:37:27 ]
きもちわるいなあ

294 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 14:40:40 ]
エチケット袋持ってきましょうか?

295 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 15:10:33 ]
いえ結構。そのまま吐きます

296 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 15:14:49 ]
キッシュを食うのとエチケット袋を使うのはガキ。

297 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 17:55:34 ]
「規格違反のプログラム」 は、
特定の環境では動くことが保証されてるかもしれないけど、
全ての環境で動く保証が無い。
だから、そのプログラムが特定の環境でのみ使用される事が決まってるなら、
規格違反でもその環境でちゃんと動作する事が保証されていれば問題ない。
ただ、色んな環境で使われるプログラムであれば、規格通りに作らないといけない。

つまりは要件次第の問題であって、常にどちらかでないといけないみたいな事を言うのは愚。

>>292
gets の使用は規格で推奨されていない。
未だ存在しているのは単に互換性のため。
セキュアCRT関数は安全だが、
GCC でコンパイルしたいような場合には
#if 使って GCC でも大丈夫なようにする必要がある。

あと、ハンドルで問題とされているのは、
ハンドルの値は別にアドレスではないのに
ポインタに入れるようにしている点。
ただ、これは int にしてしまうと安全性が低くなるし、
環境依存という程ちゃんと動かなくなる環境もないしで、
いい hack だと思う。

298 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 18:53:41 ]
話は逸れるが、ハンドルも全てがアドレス値(ポインタ)でないとは限らない。
ドラッグ&ドロップの処理などでGlobalAllocでメモリ確保したものを
HDROP型へキャストしてやるという事例がある。

ふうんと言われればそれまでのことだけど。

299 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 18:56:05 ]
それをいうなら、そもそもポインタ(というより左辺値)だってアドレス値とは限らないでしょ?



300 名前:デフォルトの名無しさん mailto:sage [2007/05/29(火) 19:02:00 ]
プログラムごとに論理的なアドレス空間を持ってるんじゃないの?
昔、物理的なアドレスを使えば一意だろうと思って使ったら、見事に失敗した。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<206KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef