【初心者歓迎】C/C++室 Ver.47【環境依存OK】at TECH
【初心者歓迎】C/C++室 Ver.47【環境依存OK】 - 暇つぶし2ch263:デフォルトの名無しさん
08/01/20 23:07:54
>>262
デバッガで動かして、fopenの中にF11キーで入ればいいだろ。
そうすりゃ分かる。

264:デフォルトの名無しさん
08/01/20 23:10:58
>>263
最近のVC++は持っていません。

265:デフォルトの名無しさん
08/01/21 00:16:01
も、もうだめだ。

さよなら単位

266:デフォルトの名無しさん
08/01/21 00:37:07
さよなら(^o^)/~~

267:デフォルトの名無しさん
08/01/21 00:40:28
Cプログラマ必須テキスト!

URLリンク(mori.eco.to)

268:デフォルトの名無しさん
08/01/21 00:48:51
>>267
経歴が恐ろしくしょぼいなwwwwwwwwwww

269:デフォルトの名無しさん
08/01/21 00:51:04
>C++未経験ながら、1人でC++の10万行のソースコードの保守及び、3万行の開発を行った。

突っ込みどころはここですか?www

270:デフォルトの名無しさん
08/01/21 00:55:57
>>260
s付いてるほうは受け渡し用のバッファサイズを指定するようになった。
バッファサイズを超えては読まないようになってる。

271:デフォルトの名無しさん
08/01/21 00:58:32
>>270
fopen_sもか?

272:デフォルトの名無しさん
08/01/21 01:04:11
errno_t fopen_s(
 FILE** pFile,
 const char *filename,
 const char *mode
);

形そのものが違うじゃん

273:デフォルトの名無しさん
08/01/21 01:12:41
悪い悪い、fopen_sの場合は
パラメータの検証が行われます。
pFile、ファイル名、またはモードが null ポインタの場合には、
「パラメータの検証」に説明されているように、これらの関数は
無効なパラメータの例外を生成します。

あとUnicode のファイル ストリームをサポートします

274:デフォルトの名無しさん
08/01/21 01:56:43
qsort関数について質問なんだが、
必ずしも内部のアルゴリズムがクイックソートだとは限らないよな?
選択ソートが使われてる気がして仕方ないんだが。

でもぐぐってみるとクイックソートが使われてるって書かれてるし…。

275:デフォルトの名無しさん
08/01/21 01:59:22
規格では具体的なソート手法の指定はないが、
O(N logN) でテンポラリバッファ不要のソート法であるという指定はあったと思う。

276:デフォルトの名無しさん
08/01/21 02:02:46
んだから、選択ソートは使われていないはず。O(N^2) だから。

277:デフォルトの名無しさん
08/01/21 02:03:29
ああ、ただし、要素数が少ない場合はわからん。

278:デフォルトの名無しさん
08/01/21 02:07:09
>>277
ありがとう。
比較関数弄ってみてるものの中々アルゴリズムが特定出来ない…。
O(N log N)だとするとやっぱりクイックソートなのかなぁ。

要素数によって使われるアルゴリズム変わるんですかね。
だとすると新しい発見かも…。

279:デフォルトの名無しさん
08/01/21 02:20:32
>>274
BCC5.9.2の実装だと途中で挿入ソートに切り替えている
要素数が10以下になると再帰呼び出しのコストが馬鹿に
ならないからだろう

280:デフォルトの名無しさん
08/01/21 02:21:47


281:274
08/01/21 02:43:21
>>279
VC++ 2005だと要素数が10個になるまではクイックソートで
それ以降は選択ソートを使ってるみたいです。多分。

282:デフォルトの名無しさん
08/01/21 02:46:44
バブルソートや挿入ソートではなく選択ソートと思った理由は何だろう?
選択ソートは交換回数が少なくて微妙に速度が違うからそこで判断したのかな。

283:デフォルトの名無しさん
08/01/21 02:49:25
安定じゃなかったんじゃないかな

284:デフォルトの名無しさん
08/01/21 03:00:25
>>282
比較関数で比較対象を出力してみて思っただけなので、
もしかしたら間違ってる可能性もあります。
一応ソースと出力結果貼っておきますね。

URLリンク(kansai2channeler.hp.infoseek.co.jp)

------ソート前------
4
5
1
2
3
>要素数:5
-----ソート開始-----
1回目: 5と 4を比較
2回目: 1と 5を比較
3回目: 2と 5を比較
4回目: 3と 5を比較
5回目: 3と 4を比較
6回目: 1と 4を比較
7回目: 2と 4を比較
8回目: 3と 2を比較
9回目: 1と 3を比較
10回目: 1と 2を比較

285:デフォルトの名無しさん
08/01/21 03:00:53
>>284
ああ、なるほど。

286:デフォルトの名無しさん
08/01/21 15:28:11
C言語で質問なのです。
下のプログラムは動作確認済みなのですが、なぜ動作するかがわかりません。
iでfor文を考えているのに、for{}の中にiがなくても、動作するのはどうしてなんでしょうか?

#include<stdio.h>

int main(void){
double a[15]={-256.0,-128.0,-8.0,-2.0,-1.3,-1.0,-0.5,0.0,1.0,1.3,2.0,8.0,128.0,256.0};
double *p;
p=a;
for(i=0;i<15;i++){
printf("%f\t%p\n",*p,p);    ←例えばこの部分がprintf("%f\t%p\n",a[i],p);とかなら納得なのですが…
p++;
}
return(0);
}

287:デフォルトの名無しさん
08/01/21 15:36:25
>>286
ポインタ習ってないの?w

288:デフォルトの名無しさん
08/01/21 15:46:18
ポインタについてはまだ理解力が足りないと思っています。

ただ、printf("%f\t%p\n",*p,p);にするなら、forの()の中身をpのみで表さないとなんか気持ち悪い気がして…
今までやってきたfor文は()の中の変数が{}の中で必ず使われてきたので…

289:デフォルトの名無しさん
08/01/21 15:50:57
確かにあんまり行儀のいいプログラムじゃないなぁ。
私ならこう書く。
#include<stdio.h>

int main(void)
{
double a[]={-256.0,-128.0,-8.0,-2.0,-1.3,-1.0,-0.5,0.0,1.0,1.3,2.0,8.0,128.0,256.0};
for (unsigned i = 0; i < sizeof(a) / sizeof(* a); ++i) {
printf("%g\n", a[i]);
}
return 0;
}
ポインタを使うならこうなるかな。
for (double * p = a; p - a < sizeof(a) / sizeof(* a); ++p) {
printf("%g\n", * p);
}
return 0;
}
いずれにしろ、定数を生のまま書くのはやめた方がいい。

290:デフォルトの名無しさん
08/01/21 15:51:24
>>286
>printf("%f\t%p\n",a[i],p)とかなら・・・
それを言うなら、printf("%f\t%p\n",a[i],&a[i]); だろ?

最後のpがokなら、*pもokだろうに。

291:デフォルトの名無しさん
08/01/21 15:51:39
>>288
p=a; //pがaの先頭(-256)を指す
printf("%f\n", *p); //pが現在指してる値(-256)を表示する
p++; //pが次の要素(0)を指す
printf("%f\n", *p); //pが現在指してる値(0)を表示する
p++; //pが次の要素(-128)を指す
printf("%f\n", *p); //pが現在指してる値(-128)を表示する
以下繰り返し
iを使ってるのは、単に繰り返し回数を数えるため

292:デフォルトの名無しさん
08/01/21 15:56:46
>>289-291
みなさんわかりやすい説明をありがとうございます。
なんとか理解できそうです。

293:デフォルトの名無しさん
08/01/21 18:26:49
>>288
繰り返し「回数」を明示するためにfor使ってるんじゃね
そのプログラムだとp+iとかp[i]とかでもいいが
ループ回数だけが重要で、何回目のループかはどうでもいいこともたまにある


294:デフォルトの名無しさん
08/01/21 20:41:09
ループ変数にunsignedを使っちゃう奴を久しぶりに見た

295:デフォルトの名無しさん
08/01/21 20:42:30
>>294
なんかまずいんですか?

296:デフォルトの名無しさん
08/01/21 20:44:46
どうみてもわざと

297:デフォルトの名無しさん
08/01/21 20:46:48
ここで聞いていいか分からないのですが、スレ違いならスレ教えてください。

目的はC++を使えるようになることです。
C++の前にC言語勉強した方がいいということで、(どっかのサイトに書いてあった)
今はC言語を勉強中ですが、
一通り勉強したらC++に移ってもいいでしょうか?
それとも、C言語をしっかりやってからの方がいいですか?


298:デフォルトの名無しさん
08/01/21 20:55:42
>>297
俺は両者を混同しなければいつ移ったって構わないと思う。
まぁせっかくCやってるんだからポインタあたりまでは勉強したほうがいいかもね。

299:デフォルトの名無しさん
08/01/21 21:12:43
>>298
ありがとうございます。
ざっと一通り勉強してから移ります。


300:デフォルトの名無しさん
08/01/21 21:13:38
自分の勉強の方針くらい自分で決めろよ
学習を進めていけば、次に何をしたらいいかくらい
自分で判断できるようになる。
C++の勉強を始めたが最期、Cの勉強には一生戻れない
というわけでもあるまいし。

301:デフォルトの名無しさん
08/01/21 21:28:36
逆に考えるんだ。
次にやるべきことを判断できるようになるまで
真面目に勉強する気が最初からないと考えるんだ。

302:デフォルトの名無しさん
08/01/21 21:47:04
というようなキチガイ的な返事しか出来ないのがプログラマw
個人的にはいきなりC++でも全然問題ないと思う。

303:デフォルトの名無しさん
08/01/21 21:57:41
>>295
> なんかまずいんですか?

・ふつーint
・差をとったりして負の数が出てくる計算で気分的によろしくない

304:デフォルトの名無しさん
08/01/21 22:31:29
>for (unsigned i = 0; i < sizeof(a) / sizeof(* a); ++i) {
forの初期化のトコで宣言出来るのってC99だっけ?

305:デフォルトの名無しさん
08/01/21 22:34:46
C++も

306:デフォルトの名無しさん
08/01/21 22:37:47
size_t型が符号なし整数として定義されている環境だと、iがsignedの場合
i < sizeof(a) / sizeof(* a);
の部分で「signedとunsigned比較すんなボケ」という警告が出るから
unsignedにしたんだろう。
だがこれだと、size_t型が符号あり整数として定義されている環境では
逆に警告が出る。
これが嫌な人は(sizeof(a) / sizeof(* a))の方をcastしたりするんだろうけど、
signedなsize_t型なんて聞いたことないからぶっちゃけどーでもいい。

307:デフォルトの名無しさん
08/01/21 22:52:47
根本的に違うんじゃね?
for文回すのにunsignedがいけないという理由は

for (unsigned i = 0; i > 0; i--) { ... }

というような回し方をしてたら、unsignedだから結局、
0未満は無いで、知らずに無限ループにハマってしまうからやめろ
とか、そんな理由の奴は聞いた事がある

308:デフォルトの名無しさん
08/01/21 23:04:27
そもそも、回数が固定なループを書くときに
継続条件に < を使うのがおかしい。!=を使え。

309:デフォルトの名無しさん
08/01/21 23:15:54
signed/unsigned関係ないし・・・
iteratorならよく見るが、ふつうは不等号じゃね?

310:デフォルトの名無しさん
08/01/21 23:16:23
>>306
>だがこれだと、size_t型が符号あり整数として定義されている環境では

そんな環境ありえねー。

>>307
そのループ1回も実行されないぞ。

まずいのは、例えば i を 9, 8, ... 1, 0 としてループしたい時に

for(int i = 9; i >= 0; i--){ ... }

って書いた場合、int を unsigned int にすると、>>307 の言うようにはまる。

でも、最近のコンパイラなら i >= 0 が偽にならないとかの警告が出るものも多いよ。

>>308
ネタだろうが、それはない。

311:デフォルトの名無しさん
08/01/21 23:20:52
>>310はイテレータを使ったことがないとみた

312:デフォルトの名無しさん
08/01/21 23:26:40
俺もたまに使ってしまう>unsigned
vectorなんかを添え字で単純に回したいとき。
くせというかなんというかw

313:デフォルトの名無しさん
08/01/21 23:27:01
>>310
>>308
ネタだろうが、それはない
iteratorでなくとも
Cの場合でもループの不変な表明を考えた場合
!= を使うべきことは非常に多い。

i != NUMS

の場合、ループ終了後はi == NUMS であることが保障される。
が、i >= NUMS だとそうはいかない。

314:デフォルトの名無しさん
08/01/21 23:30:13
どっちが速いの?

315:デフォルトの名無しさん
08/01/21 23:36:47
>>314
変わらないだろ。

0との比較は速い場合がある。
for(int i=10; i; i--) { ... } // 10回ループ

316:デフォルトの名無しさん
08/01/21 23:48:01
たまに数字飛ばしたりするからi>0って書くな

317:デフォルトの名無しさん
08/01/21 23:48:47
>>315
まさか、Javaでもあるまいし普通のコンパイラは速度差がないコードを吐くと思うぞ。

318:デフォルトの名無しさん
08/01/21 23:52:24
for(unsigned int i=10; i>0; i--) { cout << i << endl; }  →期待通り
for(unsigned int i=10; i>=0; i--) { cout << i << endl; } →無限ループ

理由、
unsignedの値はmax→→→→→→0→maxになる。
上のループだと偽(i==0)があらわれる。下のループだと常に真だから無限。

おk?

319:デフォルトの名無しさん
08/01/21 23:53:20
>>318
お前は少し上のレスも読めないのか

320:デフォルトの名無しさん
08/01/21 23:55:28
>>317
0との比較はゼロフラグを使えるので、効率が良い。
アセンブラの話な。
もちろん、命令パイプラインの効果で差が無くなるかもしれないが、
「場合がある」ということで。

321:デフォルトの名無しさん
08/01/21 23:56:48
>>319
言われて見れば同じ事言ってるw つうか微妙に違う事言ってるのかと思って。
>>319のような言葉でしっかり確信持てることもある。

ということで、言葉は人をなめてるが実は優しい>>319

322:デフォルトの名無しさん
08/01/22 00:25:21
>>320
その話を知ってからいろんな環境で実験したけど未だに実感できたことがない。
ハンドアセンブルするような環境ならそりゃ違うけど・・・

323:デフォルトの名無しさん
08/01/22 00:32:33
>>322
だって期待できるコード削減量って
ループ1回につき比較命令1つ程度なんだから、
実感は難しいかなあ。

324:デフォルトの名無しさん
08/01/22 00:40:25
いや、実験はそりゃ億とか兆とかするよ?
CPUの周波数がわかってれば期待できる短縮時間は予測できるじゃん?
んでも、どんだけ回しても測定誤差程度の値しか出ないんだよ・・・逆転も往々にしてあるし。

325:デフォルトの名無しさん
08/01/22 00:43:08
なんか自分で書いててアセンブラで比較してステート数確認すりゃいいじゃんとか思ってしまった・・・

326:デフォルトの名無しさん
08/01/22 00:45:59
アセンブリ吐いて比較してるよね?
場合によっては逆順に最適化されることもあると聞いた事あるが。

327:デフォルトの名無しさん
08/01/22 01:02:26
>>306
規格でsize_tは符号なしと決まっている。

328:デフォルトの名無しさん
08/01/22 02:08:21
VC9なんですけど

#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)

このマクロをもっと圧縮できませんか?
二行くらいに。

329:デフォルトの名無しさん
08/01/22 02:15:54
できないから3行なんだ。

#define WIDEN(x) L#x
#define __WFILE__ WIDEN(__FILE__)

VC9を持ってないからこれがコンパイル通らなきゃ不可能。
ってか通ったところでほかの環境でも通るとは限らないが。

330:デフォルトの名無しさん
08/01/22 02:19:00
真ん中飛ばせる希ガス

331:デフォルトの名無しさん
08/01/22 02:30:20
みり

332:デフォルトの名無しさん
08/01/22 03:03:03
switchでcaseが大量にあるときに、
高速化を狙って関数ポインタの配列に
するって手があると思うんですが、
ポインタ関数の呼び出しのオーバーヘッドは
case何回くらいに匹敵するんでしょうか?

皆さんだったらcase何回くらいからポインタ関数
配列に換えますか?

333:必要なら実測するのみ
08/01/22 03:09:58
>>332
case by case.

334:デフォルトの名無しさん
08/01/22 03:11:00
>>332
そういう風に出来る switch は
普通はジャンプテーブルに最適化されるから
気にしなくてもいいぜ。

関数ポインタを使うのは高速化を目的とするものじゃなくて、
実装の利便性やら可読性やらを目的とするもんだ。

335:デフォルトの名無しさん
08/01/22 03:13:25
>ジャンプテーブルに最適化される

そうだったのか!w
わざわざ変えてたのは無駄だったんですね。

336:デフォルトの名無しさん
08/01/22 03:17:03
実は、関数テーブルではなくジャンプテーブルなので、手動で関数テーブルにするより高速。

337:デフォルトの名無しさん
08/01/22 03:28:00
>>332 実際は、ifで分岐を書いた方が高速
もし等確率で起こるならcaseの最適化がifより速くなることもあるが
CPUには分岐予測があり、30%くらいを占める分岐があればそれを始めに判定することでかなり速くなる

338:デフォルトの名無しさん
08/01/22 03:31:04
テーブルにアクセスする時間との兼ね合いで
ジャンプテーブルに最適化するかどうか
決めてたりしないのか? コンパイラは。

339:デフォルトの名無しさん
08/01/22 03:33:00
>>337
分岐数が100とか1000とかに達するような場合でも
CPUの分岐予測って効果あるんですか?

340:デフォルトの名無しさん
08/01/22 03:40:54
既存のクラスParentを新しいクラスChildに継承させたいのですが、Parentに規定のコンストラクタがなく、必ず引数を必要とする場合の子クラスのコンストラクタの書式が分かりません。
親切な方、どうか助けて下さい。

341:デフォルトの名無しさん
08/01/22 03:46:18
初期化子つけりゃいいだけじゃん

342:デフォルトの名無しさん
08/01/22 05:29:02
>>341
初期化子に親クラスで定義されている変数を引数として使えないことを知らなかった…
親クラスに少し手を加えて自己解決しました

343:デフォルトの名無しさん
08/01/22 08:50:36
勘違いしてる悪寒

344:デフォルトの名無しさん
08/01/22 10:23:40
wchar_tについて質問です。
実装によってはwchar_tのサイズは2byteなようですが、これはサロゲートペアは
どのような扱いになるのでしょうか?

1.サロゲートペアは見なかったことにする。結果サロゲートペアが必要な文字は文字化けする。
2.サロゲートペアも適切に処理。結果文字列の長さが変わる。

345:デフォルトの名無しさん
08/01/22 11:29:00
初心者です。ある多元配列をkaiseki.cvsで与えた時に
それの行と列を入れ替えるようなプログラムを考えています。

教科書を見たところ、1次元配列についてはfgets,fgetcを使えばいいという事はわかったのですが
多元配列になると、そもそもfgetsがどういうタイミングで一行を読み取るのかよくわかっていないので
for文の中にどうやって組み込めばいいのかわからず、さらには読み取ったものを
どうやって多元配列になおせばいいのかわかりません。
とりあえず自分で試行錯誤してみたのを張っておきます

URLリンク(kansai2channeler.hp.infoseek.co.jp)

346:デフォルトの名無しさん
08/01/22 12:18:45
fgetsは改行までを読み込むんだよ。

347:デフォルトの名無しさん
08/01/22 12:54:32
取り敢えず、kaiseki.cvsなんて名前はやめよう。誤解の元だ。

348:デフォルトの名無しさん
08/01/22 12:59:32
>>328

#define AL2TL(x) TEXT(##x##)
#define __TFILE__ AL2TL(__FILE__)

とか

349:デフォルトの名無しさん
08/01/22 13:13:53
VC2008で、「where」という単語使うと
予約語みたいで青くなるんですけど。
.NETの予約語みたいなんで使ってもいいですか?

350:デフォルトの名無しさん
08/01/22 13:19:14
>>344
wchar_tの中身がUnicodeとは限らないので、その質問は一般的には無意味。

で、Windows環境は確かにwchar_tは2バイトなんだけど、サロゲートペア
が問題になるかどうかはどういう処理をするかに依存するので、やるこ
とをもっと具体的に書いたほうがいいかも。



351:デフォルトの名無しさん
08/01/22 13:21:48
言語周りのAPIなり何なりに任せるしかないんじゃね?

352:デフォルトの名無しさん
08/01/22 14:18:45
文字数を数えたいときって,サロゲートペア以外に
合成文字も考えなきゃだめだよね?
もう,ウンコでそう.

353:デフォルトの名無しさん
08/01/22 15:22:27
もう1文字8バイトにしちゃいなYO

354:デフォルトの名無しさん
08/01/22 18:39:31
>>349
whereは予約語になる予定だったが
よく使われていたので却下された。よって使ってよし

355:デフォルトの名無しさん
08/01/22 19:09:07
みんな大好きデバナガリ

356:デフォルトの名無しさん
08/01/22 19:38:53
あなたも私も結合音節

357:デフォルトの名無しさん
08/01/22 22:06:55
>>350
確かに仕様ではwchar_tの中身もサイズも未定義でした。すいません。
やりたいことは、UTF-8のテキストをFreeTypeに突っ込みたいのですが、よくよく考えたら
FT_Get_Char_Indexの引数はFT_ULongで32ビットでした。
サロゲートペア関係ありませんでしたねOTL

358:デフォルトの名無しさん
08/01/23 15:19:28
#define max(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \ ←これ
_x > _y ? _x : _y; } )

上記の4行目だけ良く判りません。
これは、変数_x と _y の格納場所アドレスが同じ場合、
真(1)になるという意味だと思いますが、文がここで終わって
まして、このような場合どのように解釈されるんでしょうか?


359:デフォルトの名無しさん
08/01/23 15:33:22
型が違う場合に(intとdoubleのmaxとか)コンパイルエラーを起こさせて
落とすための仕掛けじゃないかという気がする。確かめたわけじゃ
ないからほんとにそうなるかわかんないけど。

360:358
08/01/23 15:53:12
gcc 3.4.4 で int と long 型の変数を max に与え、4行目のあり・なしでコンパイルしてみた所、
確かにありの場合だけ
warning: comparison of distinct pointer types lacks a cast
が出ました。なるほどー

ちなみに、_x > _y でも比較を行っていると思うのですが、ここでは弾かれないんですね…


361:デフォルトの名無しさん
08/01/23 15:55:44
数値の比較は暗黙の型変換されるからね。
ポインタだとそれがない。

362:358
08/01/23 16:03:06
よく分かりました。ありがとうございました。


363:デフォルトの名無しさん
08/01/24 13:08:33
cabファイルに、ファイルを追加圧縮したいのですが、DLLの説明書には出来ないとあります
しかしアーカイバで対応しているものがあります
C言語ではどのようにやればいいのかわかりますか

364:デフォルトの名無しさん
08/01/24 13:13:15
一旦どこかに展開してから再圧縮してるのでは。

365:デフォルトの名無しさん
08/01/24 13:15:21
そうみたいです ありがとうございます

366:デフォルトの名無しさん
08/01/24 14:25:20
昔のVCの話ですが。



367:デフォルトの名無しさん
08/01/24 14:25:38
めでたし、めでたし。

368:デフォルトの名無しさん
08/01/24 14:29:54
日本語のWindows98で動くプログラムは_MBCS指定しますか?

369:デフォルトの名無しさん
08/01/24 16:00:55
ケースバイケース

370:デフォルトの名無しさん
08/01/24 19:33:00
32bit数どおしの足し算が範囲を超えたのかチェックするにはどうすればいいですか if無しで出来ますか

371:デフォルトの名無しさん
08/01/24 19:37:22
a、bが1ビットならば

a + b = (a and b, a xor b)_(2)

ですが32bitはどうすればいいですか

372:デフォルトの名無しさん
08/01/24 19:41:31
複数ビットの加算器
URLリンク(ja.wikipedia.org)

373:デフォルトの名無しさん
08/01/24 19:42:57
>>370
何も考えずに、一番簡単なやり方でやろうと思えば、64bit整数にキャストして足し算してしまうことだな。
後は(a+b) と aの大小を比較するとか。

374:デフォルトの名無しさん
08/01/24 19:45:23
比較とかキャストしないでマシンに手間がかからないでやる方法ないですか

375:デフォルトの名無しさん
08/01/24 19:48:02
>>372
C言語は、1bit単位の変数ないし、加算器をソフトウェアで実装すると鈍いです
速い方法ないですか

376:デフォルトの名無しさん
08/01/24 19:50:15
a + b > INT_MAX
    ↓
a > INT_MAX - b

377:デフォルトの名無しさん
08/01/24 19:51:39
1bitみたいに桁上がりをandや+を使ってわかりませんか

378:デフォルトの名無しさん
08/01/24 19:53:06
比較っつっても真偽値取得するだけなら setxx 命令使えるから遅くはならないと思うがね。

379:デフォルトの名無しさん
08/01/24 19:57:07
キャリーフラグとか? まぁ、どっちにしても比較はいるわなぁ……

380:デフォルトの名無しさん
08/01/24 19:58:15
a + bで、
aとbの符号が異なれば、オーバーフローすることはない。
同符号の場合、aやbの符号とa + bの符号が異なれば、オーバーフローしている。

381:デフォルトの名無しさん
08/01/24 19:59:57
インラインアセンブリ?

382:370
08/01/24 20:02:29
いい方法みつけたような気がします
unsigned intだとします 桁上がりが起こるならどちらかの31bit目が1です
2^32からその数を引けばあといくつで桁上がりするかわかります
そこで2の補数を求めてから2つの数を足してみて、31bit目が1なら負なので桁上がりしません

383:デフォルトの名無しさん
08/01/24 20:03:00
mov eax, a
xor edx, edx
add eax, b
setc dl

もうこれでええっしょ。

384:370
08/01/24 20:10:10
間違えました でもいい線いってるきはします

385:デフォルトの名無しさん
08/01/24 20:10:12
OFビットを見るほうがいいんでね?

386:デフォルトの名無しさん
08/01/24 20:13:44
久しぶりだからOFとか忘れてたお・・・

387:370
08/01/24 20:17:58
a+b;
のあとにOFはどうすれば調べられるんですか

388:デフォルトの名無しさん
08/01/24 20:18:43
インラインアセンブリでごりごり

389:デフォルトの名無しさん
08/01/24 20:21:59
((a >> 1) + (b >> 1) + (a & b & 1)) & 0x80000000

これでどうよ?
シフト2回入っちゃうけど。

390:370
08/01/24 20:27:42
良いですね
下位1bitの桁上がりを求めて、1bitシフトさせたものに加えれば桁上がりがわかりますね 
サンクス

391:デフォルトの名無しさん
08/01/24 20:29:19
何か a >= (unsigned)-b の方が速い気がする。
ちゃんと実測してソースつきで報告よろ。

392:デフォルトの名無しさん
08/01/24 20:41:43
符号ありなの無しなの?

393:デフォルトの名無しさん
08/01/24 20:44:21
なしっぽい流れ

394:370
08/01/24 20:58:30
なんか、if文の方が速いかも・・・BCC5.5の場合
#include <iostream>
#include <time.h>
using namespace std;
#define N 1000000
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)

main(){
unsigned int *a=new unsigned int [N];
unsigned int *b=new unsigned int [N];
int n,cl,clsum[3],s=0;
for(n=0;n<3;n++)clsum[n]=0;
for(n=0;n<N;n++){ a[n]=rnd(); b[n]=rnd();}

for(int k=0;k<200;k++){
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]>>1)+(b[n]>>1)+(a[n]&b[n]&1))>>31;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){unsigned int x=a[n],y=b[n];s+=((x>>1)+(y>>1)+(x&y&1))>>31;}clsum[2]+=clock()-cl;
}
cout<<"if文の速度 "<<clsum[0]<<endl;
cout<<"if無しの速度1 "<<clsum[1]<<endl;
cout<<"if無しの速度2 "<<clsum[2]<<endl;
}

395:デフォルトの名無しさん
08/01/24 20:59:26
>>31は遅いと思う。

396:デフォルトの名無しさん
08/01/24 21:00:27
最適化しないように文末にcout<<(s&1);を入れて下さい

397:デフォルトの名無しさん
08/01/24 21:00:39
if文じゃないだろif文じゃw
条件式だ。

398:デフォルトの名無しさん
08/01/24 21:08:11
メモリアクセスに時間かかるようなのでパラメータ変更しました これだと微妙に論理演算のほうが速いかも
#include <iostream>
#include <time.h>
using namespace std;
#define N 10000
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)

main(){
unsigned int *a=new unsigned int [N];
unsigned int *b=new unsigned int [N];
int n,cl,clsum[3],s=0;
for(n=0;n<3;n++)clsum[n]=0;
for(n=0;n<N;n++){ a[n]=rnd(); b[n]=rnd();}

for(int k=0;k<30000;k++){
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]>>1)+(b[n]>>1)+(a[n]&b[n]&1))>>31;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){static unsigned int x=a[n],y=b[n];s+=((x>>1)+(y>>1)+(x&y&1))>>31;}clsum[2]+=clock()-cl;
}
cout<<"if文の速度 "<<clsum[0]<<endl;
cout<<"if無しの速度1 "<<clsum[1]<<endl;
cout<<"if無しの速度2 "<<clsum[2]<<endl;
cout<<(s&1);
}

399:デフォルトの名無しさん
08/01/24 21:13:15
#include <stdio.h>
#include <time.h>

#define N 10000000

int main() {
unsigned a, b=0;
int k;
int cl, clsum[2] = {0};

for(k=0;k<200;k++) {
cl=clock(); for(a=0;a<N;a++)b+=(a>=(unsigned)-b); clsum[0]+=clock()-cl;
cl=clock(); for(a=0;a<N;a++)b+=((a>>1)+(b>>1)+(a&b&1u))&0x80000000u; clsum[1]+=clock()-cl;
}
printf("条件式 : %d\n", clsum[0]);
printf("ビット演算: %d\n", clsum[1]);
printf("%u\n", b);

return 0;
}

条件式 : 1004
ビット演算: 1235
1

400:デフォルトの名無しさん
08/01/24 21:14:47
最適化忘れてた

条件式 : 600
ビット演算: 677

MacOSX Core2Duo 2.16GHz gcc -O2

401:デフォルトの名無しさん
08/01/24 21:17:28
#include <stdio.h>
#include <time.h>

#define N 10000000

int main() {
unsigned a, b=0;
int k;
int cl, clsum[3] = {0};

for(k=0;k<200;k++) {
cl=clock(); for(a=0;a<N;a++)b+=(a>=(unsigned)-b); clsum[0]+=clock()-cl;
cl=clock(); for(a=0;a<N;a++)b+=((a>>1)+(b>>1)+(a&b&1u))&0x80000000u; clsum[1]+=clock()-cl;
cl=clock(); for(a=0;a<N;a++)b+=((a>>1)+(b>>1)+(a&b&1u))>>31; clsum[2]+=clock()-cl;
}
printf("条件式 : %d\n", clsum[0]);
printf("ビット演算1: %d\n", clsum[1]);
printf("ビット演算2: %d\n", clsum[2]);
printf("%u\n", b);

return 0;
}

条件式 : 566
ビット演算1: 672
ビット演算2: 701

やっぱり条件式が一番速い。

402:デフォルトの名無しさん
08/01/24 21:20:42
std::exceptionを継承して使う場合
勝手にメンバとか付け足してもいいですか?
たとえばHRESULTとか

403:デフォルトの名無しさん
08/01/24 21:20:57
ビット演算は健闘はしているけど、
いかんせん式が複雑すぎたな。

404:デフォルトの名無しさん
08/01/24 21:21:23
>>402
お好きにどうぞ

405:デフォルトの名無しさん
08/01/24 21:21:51
『最大50桁の自然数2つを、文字列として入力させて積を出す』
という問題が出たんですが。
先生とのメールのやりとり↓
私「筆算の方法で行う」
先「積は和の繰り返しで表すこともできます」
私「最初の数値を次の数値分だけ足し算する
  (2×3 = 2+2+2)」
先「桁数が多い場合単純に繰り返すだけではだめです」

どうすればいいでしょうか(:_;)
お願いします

406:デフォルトの名無しさん
08/01/24 21:22:47
コピペか?

407:デフォルトの名無しさん
08/01/24 21:24:43
>>398をVC++6でやると論理演算の方が速いよ
1248
1108
1425
となる

BCC5.5では
1931
2878
2160

408:デフォルトの名無しさん
08/01/24 21:24:43
最近どっかで見たな。

409:407
08/01/24 21:28:38
GCC(MinGW)では
829
1236
1841

同一スペックで>>398を動かしたとき

410:デフォルトの名無しさん
08/01/24 21:37:26
>>398
ウチではこうなった。
1245
688
1302

411:デフォルトの名無しさん
08/01/24 21:38:58
>>398
ウチではこうなった。
if文の速度 100
if無しの速度1 111
if無しの速度2 107

412:デフォルトの名無しさん
08/01/24 21:40:17
あまりに早く終わるので N を 10 倍した
if文の速度 896
if無しの速度1 1008
if無しの速度2 1061

413:407
08/01/24 21:47:10
単純な計算と比べてもほんど無視できる程度しか変わらなかったよ・・・

#include <iostream>
#include <time.h>
using namespace std;
#define N 10000
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)

main(){
unsigned int *a=new unsigned int [N];
unsigned int *b=new unsigned int [N];
int n,cl,clsum[4],s=0,t=0;
for(n=0;n<4;n++)clsum[n]=0;
for(n=0;n<N;n++){ a[n]=rnd(); b[n]=rnd();}

for(int k=0;k<30000;k++){
cl=clock();for(n=0;n<N;n++)t|=a[n]&b[n]&1;clsum[3]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]>>1)+(b[n]>>1)+(a[n]&b[n]&1))>>31;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){static unsigned int x=a[n],y=b[n];s+=((x>>1)+(y>>1)+(x&y&1))>>31;}clsum[2]+=clock()-cl;
}
cout<<"比較演算の速度 "<<clsum[0]<<endl;
cout<<"論理演算の速度1 "<<clsum[1]<<endl;
cout<<"論理演算の速度2 "<<clsum[2]<<endl;
cout<<"単純な論理演算の速度 "<<clsum[3]<<endl;
cout<<(s&t&1);
}

414:407
08/01/24 21:49:39
>>412
Nはランダムの2数を確保する数なので大きくすると
純正のメモリ外に書き込まれる可能性が出てきてしまいます
増やすときは、kの繰りかえし数を上げてみて下さい

415:デフォルトの名無しさん
08/01/24 21:53:01
>>414
ううん。微妙な結果。

if文の速度 1004
if無しの速度1 996
if無しの速度2 1112

416:デフォルトの名無しさん
08/01/24 21:58:55
安定して正確な速度がはかれるっぽいコードです・・・スタック領域に少量確保しました わずかに論理式のほうが速いかもしれないです

#include <iostream>
#include <time.h>
using namespace std;
#define kukikaesi 300000

main(){
#define N 1000
unsigned int a[N],b[N];
int n,cl,clsum[4],s=0,t=0;
for(n=0;n<4;n++)clsum[n]=0;
for(n=0;n<N;n++){
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)
a[n]=rnd(); b[n]=rnd();}

for(int k=0;k<kukikaesi;k++){
cl=clock();for(n=0;n<N;n++)t|=a[n]&b[n]&1;clsum[3]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]>>1)+(b[n]>>1)+(a[n]&b[n]&1))>>31;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){static unsigned int x=a[n],y=b[n];s+=((x>>1)+(y>>1)+(x&y&1))>>31;}clsum[2]+=clock()-cl;
}
cout<<"比較演算の速度 "<<clsum[0]<<endl;
cout<<"論理演算の速度1 "<<clsum[1]<<endl;
cout<<"論理演算の速度2 "<<clsum[2]<<endl;
cout<<"単純な論理演算の速度 "<<clsum[3]<<endl;
cout<<(s&t&1);
}

417:デフォルトの名無しさん
08/01/24 22:02:21
微妙すぎるのでこれにて終了します ありがとうございました

418:デフォルトの名無しさん
08/01/24 22:04:48
>>416
VC++2008EE Debugビルド
Vista Athlon Dual 4400+ 2.31GHz
比較演算の速度 2030
論理演算の速度1 2678
論理演算の速度2 1948
単純な論理演算の速度 1817

419:デフォルトの名無しさん
08/01/24 22:32:23
超初心者の質問なのですが、、、

#include <iostream>
int main() {
double a = 3.55;
int n = a * 100;
std::cout << n << std::endl;
return 0;
}

これの出力が354になります。355ではなく354になるのはどうしてなのでしょうか?




420:デフォルトの名無しさん
08/01/24 22:40:51
3.55は浮動小数点だと無限小数になって、Intに型変換すると切り捨て誤差が出る。
詳しい解説が読みたければ「浮動小数点 誤差」くらいでぐぐってみれ。

421:デフォルトの名無しさん
08/01/24 22:42:28
>>405

回数分足すのはさすがに重いだろ

一桁ずつ掛けて、そのあと和の繰り返しを使うんじゃないのか?
例えば112×235なら
5×112=560
3×112=336
2×112=224

560+3360+22400=26320
とか

まあ俺の力じゃプログラムは作れないけどなw

422:デフォルトの名無しさん
08/01/24 22:43:32
>>419
VC++ 2008 では355になる。

423:デフォルトの名無しさん
08/01/24 22:44:31
xに近い整数にするには、x +0.5を整数にすればいいのでは 変換時に切り捨てられる為

424:デフォルトの名無しさん
08/01/24 22:45:27
>>420
a * 100 ではintの100がdoubleに昇格して計算されて結果もdoubleだろ。
355になった後でintに変換されるから関係ないと思うんだが。


425:デフォルトの名無しさん
08/01/24 22:46:19
354.99999999999999999なら354

426:デフォルトの名無しさん
08/01/24 22:47:56
>>425
おお、そういうことか。あくまでも近似値なんだよな。

427:デフォルトの名無しさん
08/01/24 22:49:05
BYTE値を0.75倍し、その整数部のみを得たいのですが、
単に0.75を掛けて少数切捨てするより効率がよくて速度出る計算方法がありますかね
BYTE >> 1 のようなもの(これは1/2ですが…)があれば教えていただけませんか?

428:デフォルトの名無しさん
08/01/24 22:51:59
>>421
それ思いっきり筆算じゃね?

>>405
先生が何させたいかさっぱりわからんのだわ。
50桁くらいならFFTとか組むより筆算で十分な速度でる。
多倍長演算なら↓みたいなアルゴリズムのサイトあるけど
さすがにそんなとこまで求めてないと思うんだよな。
URLリンク(poset.jp)

429:デフォルトの名無しさん
08/01/24 22:56:19
>>427
コンパイラの最適化に任せる。

整数で処理する(最適化に負けるかもしれない)
int value = 123456;
value = value * 75 / 100;

シフト演算で頑張ってみる(1/2+1/4なので)
int value = 123456;
value = value >> 1 + value >> 2



430:デフォルトの名無しさん
08/01/24 22:56:25
>>427
(BYTE)(((WORD)x) * 3 / 4)

431:デフォルトの名無しさん
08/01/24 22:56:53
>>427
(BYTE + BYTE << 1) >> 2

432:デフォルトの名無しさん
08/01/24 22:59:31
(x + (x<<1)) >> 2

433:デフォルトの名無しさん
08/01/24 23:00:15
>>429-431
おおいろいろ方法があるんですね
みなさんありがとうございます!
早速試してみますね

434:デフォルトの名無しさん
08/01/24 23:02:56
>>428

スマン思いっきし筆算だった


435:デフォルトの名無しさん
08/01/24 23:07:35
1 の位 = 1 の位の積の 1 の位
10 の位 = (1 の位と 10 の位の積の 1 の位 + 1 の位の積の 10 の位) の 1 の位
100 の位 = 1 の位と 100 の位の積の 1 の位 + 10 の位の積の 1 の位 + (1 の位と 10 の位の積の 1 の位 + 1 の位の積の 10 の位) の 10 の位
   :
   :
   :

436:デフォルトの名無しさん
08/01/24 23:08:23
>>405
俺が思うに
お前の筆算の仕方が間違ってたんじゃないのか
筆算以外にやりようないと思うんだが

437:405
08/01/24 23:29:58
先生にまた聞いたら筆算のしかたが間違ってたみたいです、、
>>421 みたいなやりかたどうやるんですか?
ぼくのだと
「112*235=560+336+224=1120」になっちゃいます

438:デフォルトの名無しさん
08/01/24 23:31:59
桁シフトしとらんがな。
つーか、どうせならインド式実装してみたら?

439:デフォルトの名無しさん
08/01/24 23:34:32
newで配列として確保した後、その要素数を取得する方法はありますか?

440:デフォルトの名無しさん
08/01/24 23:36:15
基本的にはない。
つーか、大抵の場合は std::vector 使っておけば問題ない。

441:デフォルトの名無しさん
08/01/24 23:36:37
>>439
嫌になるほど繰り返し質問されていることですが、ありません。
newなんて使わずにstd::vectorを使いましょう。

442:デフォルトの名無しさん
08/01/24 23:36:46
ない。std::vectorでも使え。

443:デフォルトの名無しさん
08/01/24 23:37:56
std::vector 使え!

444:デフォルトの名無しさん
08/01/24 23:38:18
std::vector使えよ

445:デフォルトの名無しさん
08/01/24 23:39:02
場合によっては取得できるんだが・・・
そういう事はむやみに教えると悪い影響与えそうで困る。

446:デフォルトの名無しさん
08/01/24 23:40:03
std::vectorってなんですか?習ってないです。

447:デフォルトの名無しさん
08/01/24 23:40:19
増やした分を保持しておけばよいが、vectorは勝手に保持するからプログラムが簡単になる

448:439
08/01/24 23:40:37
みんなThx!ふと気になってレス見ないで書いちゃった、スマソ。。

449:デフォルトの名無しさん
08/01/24 23:42:03
#include <vector>
using namespace std;

main(){
vector < int > a(100);
a[0]=1; a[1]=2;
}

450:デフォルトの名無しさん
08/01/24 23:43:36
main.cpp:4: error: ISO C++ forbids declaration of ‘main’ with no type
main.cpp:4: error: ISO C++ forbids declaration of ‘main’ with no type
lipo: can't figure out the architecture type of: /var/tmp//ccLa7Foj.out
make: *** [debug/main.o] Error 1

451:デフォルトの名無しさん
08/01/24 23:48:58
今年のカレンダー表示ってどうやるんですか?

452:デフォルトの名無しさん
08/01/24 23:52:00
作って表示すれば?

453:デフォルトの名無しさん
08/01/24 23:58:43
エンディアンの勉強をしてまして、色々ググってみると、例えばリトルエンディアンの場合、
0x1234abcd の値をメモリーに格納する際、下位アドレスから順に、cd ab 34 12 と入りますが、
ここで疑問なのが、1バイトの中身のビット列はどのように扱われているのか?という点です。
1バイト8bit分のデータは、エンディアンにかかわらず常に、例えば 0x12 は、00010010 のビット列
が保たれているのでしょうか?


454:405
08/01/25 00:03:17
405ですが
筆算の問題、
>>421 
みたいに全部かけた後にまとめて足すってできるんですか?

それとも2桁ずつ掛け算して足してかないとむり?
例えば123*123だったら
123*3=369
123*2=246
  →369+2460=2829
123*1=123
    →2829+12300=15129

455:デフォルトの名無しさん
08/01/25 00:07:35
>>454
421のやりかたでできるだろ
下のだとめんどくさくないか?

よくわからんのだが

456:デフォルトの名無しさん
08/01/25 00:21:15
>>453
エンディアンは多バイトデータの配置の種類
1バイトは関係ない(同じ内容になる)

457:デフォルトの名無しさん
08/01/25 00:29:57
>>453
1バイトがどのように格納されていようが、
どうせ1バイト単位でしかメモリアクセスできないのだから、
違いは観測できないだろ。

458:457
08/01/25 00:34:10
そういえば、ビットアクセス命令のあるCPUもあるか・・・

459:デフォルトの名無しさん
08/01/25 00:40:27
1byteが12bitの環境もあるわけで

460:デフォルトの名無しさん
08/01/25 00:41:05
環境がBCCDeveloperというものです。
hoge.txtという名前のテキストファイルを作るプログラムで
同じフォルダの中にすでにhoge.txtという名前のテキストファイルがあったら
もともとあったテキストファイルの名前をhoge1.txtとして変えて新しく作るテキストファイルを
hoge.txtとすることはできるでしょうか。
できる場合はどうしたらいいでしょうか。

461:デフォルトの名無しさん
08/01/25 00:45:23
>>460
hoge.txtがあるかどうかを調べる
あったらファイル名を変更する
hoge.txtを作る

System("if exist ren hoge.txt hoge1.txt");っていけるのかな?

462:デフォルトの名無しさん
08/01/25 00:51:48
>>461
すばやい回答ありがとうございました。
早速とりかかってみたいと思います。

463:デフォルトの名無しさん
08/01/25 00:54:52
>>454
とりあえず10桁で作ってやったぞ。わからんとこあったら聞いてくれ。
#define N 10
int main( void )
{
int a[ N ] = {0,1,2,3,4,5,6,7,8,9};// 9876543210
int b[ N ] = {0,1,2,3,4,5,6,7,8,9};// 9876543210
int result[ N * 2 ] = { 0 }; // 9876543210*9876543210=97546105778997104100
for ( int i = 0; i < N; i++ ) {
for ( int j = 0; j < N; j++ ) {
result[ i + j ] += ( a[ i ] * b[ j ] );
for ( int k = i + j; k < N * 2 - 1; k++ ) {
if ( result[ k ] < 10 ) break;
result[ k + 1 ] += result[ k ] / 10;
result[ k ] %= 10;

}
}
}
for ( int i = N * 2 - 1; i >= 0; i-- ) {
printf( "%d", result[ i ] );
}
return 0;
}

464:デフォルトの名無しさん
08/01/25 01:30:19
こんなかんじか

#define kosu 4

add(unsigned int *a, unsigned int *b, unsigned int *c){
int ketaagari=0;
for(int n=0; n<kosu; n++){
c[n]=a[n]+b[n]+ketaagari;
ketaagari=a[n]>UINT_MAX-b[n];
}}

seki(unsigned int *a, unsigned int *b, unsigned int *c){

}

465:デフォルトの名無しさん
08/01/25 01:34:37
50桁までカウントさせるのが面倒で積は諦めた

466:デフォルトの名無しさん
08/01/25 04:44:04
500メガ程度の複数のテキスト文書があるとします
これから単語の頻度を求めたいとします どのようにしたらいいでしょうか?
単語は最低4バイトのものを言います
配列でカウントできないし良い方法ありますか

467:デフォルトの名無しさん
08/01/25 04:46:06
3バイトの頻度なら、int

468:デフォルトの名無しさん
08/01/25 04:49:00
>>466
最低4バイトということは200Kバイトの単語がある可能性も考慮しないとだめですか?w

469:デフォルトの名無しさん
08/01/25 04:56:06
>>468
厳密に求めなくて良いです 高頻度の単語が抽出出来ればいいです 1単語しかなければもとめなくていいです

470:デフォルトの名無しさん
08/01/25 05:01:15
一回目で24bit列を配列でカウントして、
2回目でたとえば100回以上出現したものの後ろ10バイトずつファイルに切り出して
そのファイルごとにしらべればいいか

471:デフォルトの名無しさん
08/01/25 07:23:25
>>420
ありがとうございます。なので、
0.55, 1.55, 8.55 =>切り上げなので、上記現象なし
2.55 ~ 7.55 =>切り下げなので、上記現象あり
なのですね。

ところで、上記質問をしてから色々調べたのですが、浮動小数点(例えばC言語のdouble)の
仮数部の丸めについて、丁度中間の場合は偶数になるように丸める、というルールが
あるらしいのですが、これは小数点の場合にどういう風に当てはまるのかわかりません。
これって二進数だと全部あてはまってしまうような気が、、、
どうなっているのでせうか


472:デフォルトの名無しさん
08/01/25 07:36:58
>なのですね。
いいえ。

473:デフォルトの名無しさん
08/01/25 11:27:52
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void fileread(int,char * []);
int main(int argc ,char *argv[])
{ if(argc!=3){printf("次回から引数を入力してください\n");
return 0; }
if(!strcmp(argv[2],"r")){ fileread(argc,argv);
}
return 0;}
void fileread(int argc,char *argv[]){
FILE *fp;
char *buffer,*str,*n,*s;
fpos_t start_fpos;
int filesize,count=0;
fp=fopen(argv[1],"r");
fgetpos(fp,&start_fpos);
fseek(fp,0,SEEK_END);
filesize=ftell(fp);
fsetpos(fp,&start_fpos);
buffer=(char *)malloc(sizeof(char)*filesize);
str=(char *)malloc(sizeof(char)*1000);
printf("検索する文字列を入力してください\n");
scanf("%s",str);
while(s=fgets(buffer,filesize,fp)){
count++;
n=strstr(buffer,str);
if(n){printf("%d行目 %s",count,s) };
}
free(buffer);
fclose(fp);
}

474:473
08/01/25 11:30:38
>473
csvファイル検索プログラムを作ったのですが、ファイル名にワイルドカードが使えないので
実用性にかけます。上記のプログラムにワイルドカードの組み込むにはどうすればいいでしょうか?
ただし、ファイル名はmain関数の引数で取得いたします。_findfirst,_findnextを使うところまでは
なんとなく理解しました。

475:デフォルトの名無しさん
08/01/25 11:34:25
>>474
環境は?
場合によっては wildargs とか使える場合もある

476:473
08/01/25 11:41:30
OSはCENTOS 5です。コンパイラにはgccを使っております。

477:デフォルトの名無しさん
08/01/25 11:56:10
ワイルドカードはどんなのを?
そのままだとシェルが勝手に展開しない?

478:デフォルトの名無しさん
08/01/25 11:57:55
>>473
またお前か。あちこちおかしなプログラムなのは相変わらずだな。
最低でも、バッファオーバフローの可能性は排除しておけよ。

479:473
08/01/25 12:20:12
>>477
*.csvとかですね。
そのままでは無理でした。

>>478
その件については、なんか知らんけどプログラムができあがりました。
あらかじめ指定されている仕様でしか作ったらいけないことになっておりまして、
どのようにすればそのようにできあがるのか悩まされている次第です。
一応さきほどのプログラムは作りましたが、io.hは無いそうで、_findnextも使えないですね。
こういうときそのヘッダファイルをダウンロードしてヘッダファイルがたくさんあるところに放りこめばいけますか

480:デフォルトの名無しさん
08/01/25 12:37:23
ヘッダだけ持ってきたって実装したライブラリが無きゃ無理だろ。
通常は、シェルが展開するんだが、、、opendir、readdir使って
正規表現で検索するとかしてみては

481:473
08/01/25 12:49:24
>>480
ありがとうございます。
階層を一段間違えておりました。
普通に通りますね。よかった・・・

482:デフォルトの名無しさん
08/01/25 13:31:29
>>472
int main() {
double d = 3.55; // ここの数字を変更する
int n = d * 100;
cout << n << endl;
return 0;
}
でも上記プログラムでは、浮動小数点の規格上、

d = 0.55, 1.55, 8.55 =>それぞれ0.5500000....1, 1.55000...1, 8.55000...1
とかになるので、100倍しても減ったように見えたりしない。
d = 2.55, 3.55, 4.55, 5.55, 6.55, 7.55 =>それぞれ2.5499999...などとなるので、
100倍すると、(double)254.99999==>(int)254などとなってしまう。

と理解していたのですが、他の方も書いてくれてたように、Visual C++ 2008でやると
d=3.55の時、355と表示されました。(gccは354)





483:デフォルトの名無しさん
08/01/25 17:29:42
VC++がx86の80ビット浮動小数点数レジスタを使い回すからかと思ったけど、
一旦64ビットでメモリに書きだすように仕向けてもやっぱり355になるな。

484:デフォルトの名無しさん
08/01/25 18:42:42
関数に配列へのポインタへ渡してデータょ書いてもらう場合
std::vector buffer(1024);
hogefunc(&buffer[0]);
とかくのは違法ですか?

485:デフォルトの名無しさん
08/01/25 18:47:47
確保したバッファサイズをはみ出さないのなら問題ない

486:デフォルトの名無しさん
08/01/25 19:08:51
private:な物の位置調べて無理やり書き込むわけだが。

487:デフォルトの名無しさん
08/01/25 19:19:56
そういうことができるように、
vectorは生の配列同様、要素の連続性が保証されている。

488:デフォルトの名無しさん
08/01/25 19:41:51
ぬるぽ渡せば書かずに文字数返すくらいしてくれてもいいよな。
これみたいに。
URLリンク(msdn2.microsoft.com)(VS.80).aspx

489:デフォルトの名無しさん
08/01/25 20:07:37
>>488
Win32APIスレの誤爆か?

490:デフォルトの名無しさん
08/01/25 20:51:13
inline int nazo(void)
{
 return __LINE__;
}

呼び出すと戻ってくるのはどこのあれですか?

491:デフォルトの名無しさん
08/01/25 20:52:04
そこ

492:デフォルトの名無しさん
08/01/25 20:59:02
たぶん3

493:デフォルトの名無しさん
08/01/25 21:01:39
__LINE__やら__FILE__やら__func__はコンパイル時に埋め込まれる

494:デフォルトの名無しさん
08/01/25 21:02:18
__func__ マクロじゃなくて定数だったはず。

495:デフォルトの名無しさん
08/01/25 21:09:16
ik88
ectuo\
}{([8
]\@p :
dcdc
dcdcdcfvfv7qa11111111111111111111111111111111
mnbcadcfvghujk,ol9iikurf4ed333333333333333331W2E3TR4G56







496:デフォルトの名無しさん
08/01/25 21:38:01
きーけぼーどのいちばんうきえらをうつと

12w3e4rgt5h6789o0:^\
!"#$G%H&'()~*=~|

とにゅうりょくされます。
こしょうですか?

497:デフォルトの名無しさん
08/01/25 21:41:14
pepper

498:デフォルトの名無しさん
08/01/25 21:55:26
スキンラインの短絡

499:デフォルトの名無しさん
08/01/26 03:17:03
APIについての質問です。
Visual C++ Express 2008で英単語印刷ソフトを作っているのですが、
ウインドウに、ネットの検索欄のような入力欄を作ることは可能でしょうか?
それを使って単語の検索機能などを追加したいのですが・・・。
もしよろしければ教授ください。

500:デフォルトの名無しさん
08/01/26 03:55:07
VCスレかAPIスレ池。

501:デフォルトの名無しさん
08/01/26 09:28:53
>>482
gccでも、-msse2オプションをつけてコンパイルすると、355を返すバイナリを作れました。
でも、80ビットでも、52ビットでも、切り捨てになるから、どちらでも同じと思うんですが。
なんでだろう。

502:デフォルトの名無しさん
08/01/26 11:06:09
>>501
>482のコードだけなら、最適化で定数は事前(≒コンパイル時)計算されるから不思議ではない。

503:デフォルトの名無しさん
08/01/26 20:29:17
>>502
以下のコードでも、dに3.55を入力すると、表示は354になりますが、
-msse2でコンパイルすると355になりました。

int main(int ac, char **av)
{
double d;
cin >> d;
int n = d * 100;
cout << n << endl;
return 0;
}


504:デフォルトの名無しさん
08/01/26 22:23:27
確認のために聞きたいんです
関数テンプレートについてなんですが。

template<typename T>
void func(){
 hoge = new T();
}
func<HogeClass>();

つう書き方に、何か問題はありますか?
一応BCCでは動いてるようなんですが、
検索しても基本的に引数のために使われていて、
こういう書き方を見つけられなかったので不安なんですが。

505:デフォルトの名無しさん
08/01/26 22:31:16
>>504
全然問題ない。それができないならテンプレートの魅力が半減ですよ。

506:デフォルトの名無しさん
08/01/26 22:48:00
>>505
どうもです。こういう使い方はやっぱり便利なんですね。
でも、混乱もしそう。使いこなせるよう精進します。

507:デフォルトの名無しさん
08/01/26 22:59:43
>>503
手元のgccだとそのコードでも355になるよ。354になるときの値をprintf("%.20g", d * 100)で出してみて。

508:デフォルトの名無しさん
08/01/27 03:55:57
C++ で、perl の Data::Dumper みたいなことするのがあれば
教えてください。

509:デフォルトの名無しさん
08/01/27 04:19:52
テキストファイルをchar型に読み込んだ場合って改行があったら\nもちゃんと格納されるの?

510:デフォルトの名無しさん
08/01/27 04:20:23
読み込みかたによる。

511:デフォルトの名無しさん
08/01/27 04:34:30
ありがとう。読み方によるのね
できれば\nが格納される読み方の例教えていただきたい

512:デフォルトの名無しさん
08/01/27 04:35:07
fgets

513:デフォルトの名無しさん
08/01/27 04:38:01
ファイルの開き方も重要じゃないか

514:デフォルトの名無しさん
08/01/27 04:42:08
>>512
ありがとうございます。
fgetsって\nの手前までしか格納されないかと思ってたけど\nもちゃんと入るんですね
とりあえず色々試してみることにします

515:デフォルトの名無しさん
08/01/27 04:44:40
gets以外なら大体¥nもコピーする。fgets、fgetln、テキスト指向ですらないfreadも勿論。というかgetsは絶対使わない方が良い。
C++は…誰かお願い。

516:デフォルトの名無しさん
08/01/27 07:26:38
C++でWindowsでのDLL作成に関して質問です。
C++のクラスをエクスポートする場合、純粋仮想クラスを利用するようですが、この際、
多重継承は可能なのでしょうか。具体的には以下のようなことをしたいのです。
class IFoo{
public:
virtual void fooFunc() = 0;
};

class IBar: public IFoo{
public:
virtual void barFunc() = 0;
}

class CFooFunc{
public:
virtual void fooFunc(){ /*...*/ }
};

class CBarFunc{
public:
virtual void barFunc(){ /*...*/ }
};

class CExport: public IBar, CFooFunc, CBarFunc{
};

__declspec(dllexport) IBar* createIBar(){
return new CExport();
}
__declspec(dllexport) IBar* deleteIBar( IBar* p ){
delete p;
}

517:デフォルトの名無しさん
08/01/27 09:21:25
>>511
istream& istream::get(char& c)
istreambuf_iterator
unsetf ios::skipws and istream_iterator

518:デフォルトの名無しさん
08/01/27 09:55:57
>>516
DLL でクラスを公開したいなら COM

519:デフォルトの名無しさん
08/01/27 12:57:31
COM なんて使いにくいもんじゃなくて
__declspec(dllexport) と __declspec(dllimport) を使おうぜ。
DLL と EXE で自動的に切り替えるマクロもあったけど忘れた。

520:デフォルトの名無しさん
08/01/27 14:30:07
C++の初心者向けサイトを教えてください


521:デフォルトの名無しさん
08/01/27 14:33:05
#ifdef PROJECTNAME_EXPORTS
# define DLL_EXPORT __declspec(dllexport)
#else
# define DLL_EXPORT __declspec(dllimport)
#endif

522:デフォルトの名無しさん
08/01/27 15:45:56
そういうやつ、自分で作らなくてもあったと思うけど、
自分で作った方が細かい制御ができていいかもしれん。

523:デフォルトの名無しさん
08/01/27 17:48:38
dllexportは所詮同じヴァージョンのコンパイラ相手でしか使えないからね。

524:デフォルトの名無しさん
08/01/27 18:11:43
しかし、COM は COM で色々と不便だからなあ・・・。
IA ← A の機能強化版として IB と B を別途作るとして、

 IA
↑ ↑
IB A
↑ ↑
 B

こういう継承したいけど無理っしょ?
仮想継承がないから・・・。

525:デフォルトの名無しさん
08/01/27 18:27:47
ATLみたいに実装をテンプレートに分離すれば解決しない?

526:デフォルトの名無しさん
08/01/27 23:15:08
wchar_t(unsigned char) に入ったUTF16の日本語を
ShiftJISに変換してxharに突っ込む処理を
STLだけで書くにはどう書けばいいですか?

527:デフォルトの名無しさん
08/01/27 23:26:27
std::codecvt使う例が
URLリンク(hw001.gate01.com)
にあるけど、UTF16、ShiftJISと指定した
std::codecvtをどう取得するのかは知らない

528:デフォルトの名無しさん
08/01/27 23:48:39
>>525
テンプレートは解決策の1つだとは思うけど、
ヘッダファイルに実装するのはどうもね・・・。
コードいじったときのコンパイル範囲が広くなると困るし。

529:デフォルトの名無しさん
08/01/28 00:07:40
OSに頼ったほうが安全

530:デフォルトの名無しさん
08/01/28 00:09:31
>>524
そのIAをIUnknown、Aを適当なインタフェースに置き換えれば、そんな例は山ほどある。

Aの実装をソースコードの形で手に入れられるなら、
普通にIBとAを多重継承して、細かいところを整えればいける。

531:デフォルトの名無しさん
08/01/28 00:28:36
>>530
むむっ。詳しくお願いします。

532:デフォルトの名無しさん
08/01/28 01:31:57
>>530
要は、本来Bでオーバーライドする必要のない関数も、B内から手動でAの実装を呼ぶようにすればいい。
インタフェースはメンバ変数ないから、キャスト関係くらいしか仮想継承の有無の違いはないといっても過言ではない。
struct IA : IUnknown {virtual HRESULT STDMETHODCALLTYPE FnA() = 0;};
struct A : IA {
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(IID&, void**) {/*実装*/}
    virtual ULONG STDMETHODCALLTYPE AddRef() {/*実装*/}
    virtual ULONG STDMETHODCALLTYPE Release() {/*実装*/}
    virtual HRESULT STDMETHODCALLTYPE FnA() {/*実装*/}
};
struct IB : IA {virtual HRESULT STDMETHODCALLTYPE FnB() = 0;};
struct B : A, IB {
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(IID&, void**);
    virtual ULONG STDMETHODCALLTYPE AddRef() {return A::AddRef();}
    virtual ULONG STDMETHODCALLTYPE Release() {return A::Release();}
    virtual HRESULT STDMETHODCALLTYPE FnA() {return A::FnA();} //オーバーライドしない気なら
    virtual HRESULT STDMETHODCALLTYPE FnB() {/*実装*/}
};
HRESULT STDMETHODCALLTYPE B::QueryInterface(IID& riid, void** ppv) {
    if (ppv == 0) {
        return E_POINTER;
    } else if (riid == IID_B)     {
        *ppv = static_cast<IB*>(this);
        AddRef(); //直接A::AddRef()でも可
        return S_OK;
    } else {
        return A::QueryInterface(riid, ppv);
    }
}
Javaのインタフェースの仕様だとBでのAddRef以下のようなことを書く必要がなかった気がする、ちょっとうらやましい。


533:デフォルトの名無しさん
08/01/28 01:34:43
委譲するわけですか。
うーん。委譲のコストが少し気になってしまいますね。
そんなもんなんでしょうか。

534:デフォルトの名無しさん
08/01/28 13:31:23
自分クラスに大小比較の演算子を定義して、<=を使おうと思ったら、
<と==の2つを定義するのではなく、<=を定義しないとだめだったのですが、
そういうものなのですか?


535:デフォルトの名無しさん
08/01/28 13:33:46
そういうものです。
そもそも、'<='が「小なりイコール」であると言う意味から再定義するわけですから。

536:デフォルトの名無しさん
08/01/28 13:35:16
>>534
つ[boost::operators]

537:デフォルトの名無しさん
08/01/28 14:14:23
>>534
以下は違う関数だからねえ
operator<()
operator=()
operator<=()
<=を使うということはoperator<=()をコールするわけで。

538:デフォルトの名無しさん
08/01/28 16:23:28
>>535-537
ありがとうございます。じゃあ自分クラスについては、なるべく「<=」は使わずに
<と==でなんとかするようにします。
boost::operatorsは、<と==をconst関数で定義して、publicでboost::operatorsを
継承すれば動きました。かなり便利そう。
ありがとうございました。

539:デフォルトの名無しさん
08/01/28 18:45:01
typedef struct { .... } hoge_struct;

#define TARGET_STRUCT hoge_struct
#define TARGET_STRUCT_STR ????????????

printf("type: %s\n", TARGET_STRUCT_STR );
printf("size: %d\n", sizeof(TARGET_STRUCT) );

表示
type: hoge_struct
size: 40

TARGET_STRUCTにあるhoge_struct部分は、任意の構造体名です。(色々変化します)
TARGET_STRUCT_STRが "hoge_struct" に(文字列)なるようにしたいのですが、
どんなマクロにすればいいのでしょうか?

540:デフォルトの名無しさん
08/01/28 18:52:07
言葉足らずでした。
型名であるTARGET_STRUCTを元に、文字列なTARGET_STRUCT_STRを作りたいという意味です。

541:デフォルトの名無しさん
08/01/28 18:58:47
# TARGET_STRUCT

542:デフォルトの名無しさん
08/01/28 19:11:51
>>541 ありがとうございました。

543:デフォルトの名無しさん
08/01/28 19:28:58
>>538
なんとかするとかじゃなくて「<」と「==」から「<=」を作ればいいじゃんか。
「<」と「==」が定義されてるならば「<=」は↓のようになる。
return A < B || A == B;
boost::operatorsは内部でそういうことをやってるだけ。


544:デフォルトの名無しさん
08/01/28 21:53:36
 よろしくお願いします。
 項書き換えを行うシステムを作るにあたって、今式の構造を木構造で表すことを考えています。
式は中値記法で書かれているので、基本的には一般的な構文木のように作ろうと思っています。
具体的には、ある内部ノードには演算子を格納し、その左と右の子供に項を格納するような2分木です。
 2項演算を表現するのにはこれで十分なのですが、 (X, Y, Z) のような三つ組みも表現しなければならないのです。
子供を3つ持つような木を作って、三つ組みを表現するときだけ3つ目の子供に項を格納すれば表現は可能になるのですが、
頻繁に三つ組みが現れるわけではないので、余分な子供はあまり持たせたくないと思っています。
 2分木で三つ組みを表現するうまい方法はないでしょうか。


545:デフォルトの名無しさん
08/01/28 21:56:16
演算子 A を考える場合に

   A1
   ∧
   X A2
    ∧
    Y Z

みたいにすればいいんじゃない?

546:デフォルトの名無しさん
08/01/28 22:00:04
単項演算子で無駄なノードが発生するのは別に構わんのん?

547:デフォルトの名無しさん
08/01/28 22:01:13
各ノードはふたつのポインタをもち、
それぞれは、
・自分の子供のひとつ(長男)
・自分のすぐ下の弟
を指すようにすれば2分木でいくらでも子供を持てる。
これは木構造を作るのに定番の方法なので覚えておくといいよ。

548:デフォルトの名無しさん
08/01/28 22:44:46
Visual Studio 2005なんですが、vector型の変数で名前をarrayにしたら、変数名が青くなってました。

intみたいに予約語なのかなとも思ったんだけど、特に問題なく動くんですが、青くなるのはなんでなんでしょう?

549:デフォルトの名無しさん
08/01/28 22:50:10
>>548
arrayはCLR配列の予約語だからじゃない?

550:デフォルトの名無しさん
08/01/28 22:59:40
>>549
即レスありがとうございます!
ほうほう、CLR配列で調べると確かに予約語っぽいですね。でも問題なしと考えてよいんでしょうか。

ついでにうかがいたいんですが、ちょい前までVC++6.0でつくっていたソースコードがあって、関数の引数にbool型をつかっていました。

そのソースを2005でダイアログベースで作っているプロジェクトで利用しようと思ったんですが、チェックボックスのValueがBOOL型になってまして、そのまま関数の引数にぶち込むと、次のように怒られました。

>warning C4800: 'BOOL' : ブール値を 'true' または 'false' に強制的に設定します (警告の処理)

これはどうすればよいんでしょう?

551:デフォルトの名無しさん
08/01/28 23:02:56
BOOL変数?true:false
とか。BOOLってintだからなー。
TRUE/FALSEの代わりに「エラー値」が入ってたりするし。

552:デフォルトの名無しさん
08/01/28 23:09:57
>>551
うわぁお!!

すげー、通りました、感動しています。

しかし6.0から2005にするといろいろ戸惑いますね。作業効率が半分くらいになった感じです。

553:デフォルトの名無しさん
08/01/28 23:37:08
>>545
 そうですね、こちらでも考えましたが、このような木の構造にするしかなさそうですね。

>>547
 アドバイス有り難うございます。
処理系を作るときに、こういう形で構文木を作るとネストされたリストも簡単に表現できるということで、
勉強したことがありました。確かに自分もよく使います。

 お二方、どうも有り難うございました。

554:デフォルトの名無しさん
08/01/29 00:09:40
>>552
6.0から2005だと色々変えないといけないところが出てくるだろうな。
new 失敗した時デフォで NULL 返すような古いコンパイラだからなあ。
まあ、変更が終われば大した違いはなくなると思うぜ。

555:デフォルトの名無しさん
08/01/29 00:46:03
LONG a=適当;
LONG b=適当;
LONG c=適当;

if(a*a + b*b > c*c) {
}

とした時に、
a*a等がLONGに収まる範囲を超えてしまったら、
どうなるのでしょうか?

556:デフォルトの名無しさん
08/01/29 00:56:45
>>555
LONGがlongのtypedefなら未定義

557:デフォルトの名無しさん
08/01/29 01:22:40
STLでウィンドウへ作ったり絵を描くクラスはどこにありますか?

558:デフォルトの名無しさん
08/01/29 01:23:49
ありません
gilを使ってください

559:555
08/01/29 01:32:29
>>556
Win32APIを使ったプログラムで、
LONGは<windows.h>に定義されているモノです。たぶん。
未定義というのは、どうなるか分からないということですか。

560:デフォルトの名無しさん
08/01/29 01:33:46
世界ランク14位おめw
URLリンク(2chcity.myminicity.com)

ランク   国名      街             人口  (前日比)  前日
--- 1   US1      LUELand         326354 (+211)   326143
--- 2   US2      GoonTown        179482 (+711)   .178771
--- 3   Germany1  .isnichwahr.de       119091 (-654)   119745
--- 4   US3      CreateMyCity Forum  .87380  (+1982)   85398
--- 5   Poland1    #debian.pl         79594  (+1043)   .78551
--- 6   Germany2  upOTia             52443  (+399)    52044
--- 7   France1    Reze'Les Nantes     .41960  (+246)    41714
--- 8   Canada1   J-C Satanas & CO   .40995  (+721)    40274
--- 9   US4      retromundi        .40604  (+788)    39816
--- 10  France2    FanaZ           .39902  .(+1268)   38634
2↑ 11  Germany3   deluxebits         38770  .(+3199)   35571
1↓ 12  US5      .isnichwahr.at        .38234  (+78)    38143
1↓ 13  France3    gravure-news       .37204  .(+765)    36439
2↑ 14  Japan1     2ch_city          35637  .(+1970)   33667
1↓ 15  Spain1     Media-Vida         .35205  .(+686)    34519
1↓ 16  France4    Sguy            .35083  .(+1456)   33626
2↓ 17  Ireland1    .prapikilty          .35067  .(+871)    34196
--- 18  Spain2     benidaver         .34505  .(+914)    33591
--- 19  Germany4   directupload       ..32490  .(+82)    .32408
-↑ 20  Slovakia1    Legionar City       32056

561:デフォルトの名無しさん
08/01/29 01:36:39
>>559
そういうことです。

562:デフォルトの名無しさん
08/01/29 05:15:49
doubleとintの丸め誤差について質問しているものです。
SSE2命令で計算するとどうして3.55*100が355になるのか、どうしてもわかりません。
IEEEの仕様どおりの浮動小数点の計算方法だと、レジスタのサイズが52でも80でも128でも
doubleの3.55は実際には2.54999999...となってしまうと思うのですが、、、
gccでSSE2命令を有効にして作成したバイナリの逆アセンブルの結果をみると、
<元ソース>
int main(void) {
double d = 3.55;
int n = d * 100;
printf("%d", n);
}

<続く>

563:デフォルトの名無しさん
08/01/29 05:17:36
<続き>
<main関数の逆アセンブル結果>
80483c4: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483c8: 83 e4 f0 and $0xfffffff0,%esp
80483cb: ff 71 fc pushl -0x4(%ecx)
80483ce: 55 push %ebp
80483cf: 89 e5 mov %esp,%ebp
80483d1: 51 push %ecx
80483d2: 83 ec 24 sub $0x24,%esp
80483d5: dd 05 d8 84 04 08 fldl 0x80484d8
80483db: dd 5d e8 fstpl -0x18(%ebp)
80483de: dd 45 e8 fldl -0x18(%ebp)
80483e1: dd 05 e0 84 04 08 fldl 0x80484e0
80483e7: de c9 fmulp %st,%st(1)
80483e9: dd 5d e0 fstpl -0x20(%ebp)
80483ec: f2 0f 2c 45 e0 cvttsd2si -0x20(%ebp),%eax
<以下はprintfを呼んでいるだけと思うので略>
をみてもなんでこうなるのか全然わかりません。
cvttsd2siの命令が、「64ビット倍精度実数を整数値に変換して汎用レジスタに
コピーします。」という内容らしいので、この動作がキモと思うのですが、これは
中でどういう動作をしてるのだろう。誰かご存知ありせんか?

長々とすいませんどうかよろしくお願いします。


564:デフォルトの名無しさん
08/01/29 05:26:47
When a conversion is inexact, a truncated (round toward zero) result is returned.
と書いてあるから3.54になるはずなのに変だねえ。

565:デフォルトの名無しさん
08/01/29 08:06:51
>>563
逆アスじゃなく、gccのアセンブリ出力を載せてくれ。0x080484d8なんてアドレス書かれてもなんだか判らん。

566:デフォルトの名無しさん
08/01/29 09:06:52
>>565
すいません。Cのコードは先のものと同じです。
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
fldl .LC0
fstpl -24(%ebp)
fldl -24(%ebp)
fldl .LC1
fmulp %st, %st(1)
fstpl -32(%ebp)
cvttsd2si -32(%ebp), %eax
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC2, (%esp)
call printf
<以下略>


567:デフォルトの名無しさん
08/01/29 09:35:25
だから、どうして.LC0とか.LC1の定義も省略するのかなぁ……

568:デフォルトの名無しさん
08/01/29 10:46:51
>>563
> cvttsd2siの命令が、「64ビット倍精度実数を整数値に変換して汎用レジスタに
> コピーします。」という内容らしいので、この動作がキモと思うのですが、これは
> 中でどういう動作をしてるのだろう。誰かご存知ありせんか?

ここまでくるとCPUアーキテクチャマニュアル見ないとわからん。
Intelのサイトにあると思うが、日本語であるかどうかわからん。


569:デフォルトの名無しさん
08/01/29 11:03:35
CVTTSD2SI--Convert with Truncation Scalar Double-Precision Floating-Point Value to Signed Doubleword Integer

F2 0F 2C /r  xmm/m64 切り捨てを使用して、xmm/m64の 1 つの倍精度浮動小数点値を r32 の 1 つの符号付きダブルワード整数に変換する。

説明
ソース・オペランド(第 2 オペランド)の 1 つの倍精度浮動小数点値を、デスティネーション・
オペランド(第 1 オペランド)の 1 つの符号付きダブルワード整数に変換する。ソース・オペ
ランドは、XMM レジスタまたは 64ビットのメモリ・ロケーションである。デスティネーショ
ン・オペランドは汎用レジスタである。ソース・オペランドが XMM レジスタの場合は、倍精
度浮動小数点値はレジスタの下位クワッドワードに置かれる。
変換が不正確な場合は、切り捨てられた(ゼロに丸められる)結果が返される。変換の結果が
符号付きダブルワード整数の最大値より大きくなる場合は、整数不定値(80000000H)が返さ
れる。

570:デフォルトの名無しさん
08/01/29 12:08:40
本当にありがとうございます。

自分もマニュアル見てみました。
結局動作としては、
1)3.55を80bitのレジスタ上で表現する。レジスタ上では3.55よりもわずかに小さい数として存在
2)fmulp命令を使って、1)の結果と100の積を計算する。
3)上の2)の結果をcvttsd2si命令を使ってint型に変換
になると。
>変換が不正確な場合は、切り捨てられた(ゼロに丸められる)結果が返される。
354.99999..からintへの変換はどう考えても「変換が不正確な場合は、」に該当すると思うのですが、
切り捨てると、354になると思うんですが、、、


571:デフォルトの名無しさん
08/01/29 12:54:22
何度もすいません。

-msse2付きでコンパイルしても、不正確になってしまうケースがありました。
int main(void) {
double d = 32.55;
int n = d * 100;
printf("%d\n", n);
return 0;
}
あとは、512.55, 513.55とか、8192.55, 8193.55とか。(これ以外にもかなり多い)
SSE2を使ったところで完全ではないようだし、なんだか不毛な感じもしてきた。
3.55については、たまたまSSE2で上手く計算できたケース、ということかな、と。


572:デフォルトの名無しさん
08/01/29 13:05:19
>>571
>567
手元の多桁演算処理に喰わせてみようと思うのだが……

573:デフォルトの名無しさん
08/01/29 13:12:09
私の所でOptimization(最適化)レベルを切り替えて実験してみた所
-O0で354、-O1で355になりました。
コンパイラはg++3.4.5です。

ソースコードをのぞいてみると、-O0は律儀に計算していましたが、
-O1の方はいきなり定数355をロードして終了していました。

574:デフォルトの名無しさん
08/01/29 13:12:41
.file "IEEE1.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC2:
.ascii "%d\12\0"
LC3:
.ascii "pause\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $16, %eax
call __alloca
call ___main
movl $355, 4(%esp) ←これ
movl $LC2, (%esp)
call _printf
movl $LC3, (%esp)
call _system
movl $0, %eax
leave
ret
.def _system; .scl 2; .type 32; .endef
.def _printf; .scl 2; .type 32; .endef

575:デフォルトの名無しさん
08/01/29 20:52:37
std::vectorを使った場合で指定した添え字番号のオブジェクトを消す方法ってありますか?

576:デフォルトの名無しさん
08/01/29 20:58:18
vec.erase(vec.begin() + i);

577:デフォルトの名無しさん
08/01/29 22:19:04
C言語って1から覚えるとなると難しいでしょうか?

プログラム関係の職(未経験可)どうしてもやってみたくて
就こうと思ってるんだけど理系学校出てないから無謀かな…

スレ違いだったら凄くすいません…

578:デフォルトの名無しさん
08/01/29 22:21:27
まぁアレだ。プログラマ板で聞けばいいんじゃね

579:デフォルトの名無しさん
08/01/29 22:22:16
>>577
どんな人も1から覚えるわけだが。

580:デフォルトの名無しさん
08/01/29 22:26:36
パソコンとインターネット環境持ってるなら、ただでプログラミングの
勉強できるから、やってみればいいんじゃないか。

難しいかどうかは、人によるからなんとも言えない。

また、理系かどうかは思ったより関係ない。

ただし、数字アレルギーとか英語まったく読む気ないですぅとか言うなら、
やめた方がいいと思う。

581:デフォルトの名無しさん
08/01/29 23:00:31
でも、ひでーアルゴリズムのコードを見ると、
理系ってのも大事だなあと思う。

582:デフォルトの名無しさん
08/01/29 23:06:11
>>578
プログラマ板か…、予備知識無くここにカキコんじゃったからな…
次からそっちで聞いてみます

>>579
まぁそうなんですよね…<どんな人も1から
それを承知で聞いてみたんで

>>580
色々サイト巡りして知識付けようとはしてます
数字アレルギーは全く無いけど、英語が学校成績で常に2付近だったから
それが不安材料でヤバイってのは承知済み…orz

今度からプログラマ板でも行ってカキコしてみます

レスどうもでしたm(__)m



583:デフォルトの名無しさん
08/01/29 23:12:35
プログラミング関係の英語ドキュメントなんて複雑な文法とか表現使ってないから学校の成績はほとんど関係ない

584:デフォルトの名無しさん
08/01/29 23:14:29
俺も数学と英語は毎回赤点だったが今では必要なだけは出来るようになったぞ。
まあ相性と経験次第。

585:デフォルトの名無しさん
08/01/29 23:44:01
>>581
理系でもひでー奴はいくらでもいる。

>>582
> 英語が学校成績で常に2付近だったから

>>580 をよく読んでくれ、英語ができないんじゃなくて、
「英語をまったく読む気がない」ならって書いてあるだろ。

君が必要に迫られたら何とかするタイプなら、心配はない。

>>583-584 が言うように、そんなに高レベルの英語が出て
くるわけじゃないし、しかもラッキーなことにここ数年で
機械翻訳がそれなりに進化して、技術文書ならなんとなく
意味が理解できるぐらいなってきたから、あまり心配しな
くても大丈夫だよ。

586:デフォルトの名無しさん
08/01/29 23:44:45
質問させてください。以下のソースをコンパイルしたところ、エラーが吐かれたのですが、その理由が良く分かりません。

#include <fstream>
#include <TCHAR.h>
#include <string>
#include <sstream>

using namespace std;
class zantei{
private:
  // 行動データ構造体
  class Action
  {
  public:
   int No; // 行動番号 (無しなら0)
   LPTSTR Type; // 行動種類 (無しなら0)
   LPTSTR Detail; // 行動詳細 (無しなら0)
   int Damage; // ダメージ(無しなら100)
   LPTSTR Color; // 色 (無しなら0)
   int X; // マルチプレイ用の遠距離行動(無しなら0)
  };
  Action action[32];
public:
  BOOL LoadAction();
};

587:デフォルトの名無しさん
08/01/29 23:45:15
エラー:
・error C2146: 構文エラー : ';' が、識別子 'Type' の前に必要です。
・以下、変数Typeが認識されないためと思われるエラー他たくさん(24個)

全角スペースや、Typeが実は予約語だったんじゃないかとも疑いましたが、
空白はすべて半角スペースとタブ入力でしたし、TypeをiやNumに変えても同じエラーが出ました。
…ということは、完全に知らないことか、思い至っていないことによるエラーだと思われる、ということまでは考えることはできました。
どなたかご教授いただけないでしょうか。

588:デフォルトの名無しさん
08/01/29 23:45:50
ほほう
何というコンパイラで、何というメッセージが吐かれたのだい?

589:デフォルトの名無しさん
08/01/29 23:50:01
コンパイラは、Visual Studio 2005 Academic Editionです。
エラーは、>>587以外もかくとすると…、ちょっと多いので、少々お待ちください。

590:デフォルトの名無しさん
08/01/29 23:51:06
>>586
そのコピペは全角だらけやな

591:デフォルトの名無しさん
08/01/29 23:51:32
このエラーだと、通常は Type の直前にある物がおかしいんだが、
tchar.h はインクルードしてあるしな・・・。
TCHAR が大文字でも何か起きると思えないし。

592:デフォルトの名無しさん
08/01/29 23:54:24
もしかすると、
#include <windows.h>
が無かったりだったりとか?


593:デフォルトの名無しさん
08/01/29 23:54:26
>>587
全角が入ってる。間違いない。絶対だ。

594:デフォルトの名無しさん
08/01/29 23:54:56
エラー 2 error C2146: 構文エラー : ';' が、識別子 'Type' の前に必要です。
エラー 3 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
エラー 4 error C4430: 型指定子がありません - int と仮定しました。
エラー 5 error C2146: 構文エラー : ';' が、識別子 'Detail' の前に必要です。
エラー 6 error C4430: 型指定子がありません - int と仮定しました。
エラー 7 error C4430: 型指定子がありません - int と仮定しました。
エラー 8 error C2146: 構文エラー : ';' が、識別子 'Color' の前に必要です。
エラー 9 error C4430: 型指定子がありません - int と仮定しました。
エラー 10 error C4430: 型指定子がありません - int と仮定しました。
エラー 11 error C2146: 構文エラー : ';' が、識別子 'LoadAction' の前に必要です。
エラー 12 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
エラー 13 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
警告 14 warning C4183: 'LoadAction': 戻り値の型がありません。'int' を返すメンバ関数とみなします。

これよりしたのエラーは、LoadAction()の実装部分で吐かれているエラーです。

595:デフォルトの名無しさん
08/01/29 23:55:00
>>592
そうか。撤回する。

596:デフォルトの名無しさん
08/01/29 23:55:42
>>594
全角入りのソースでそれと同じエラーを見たぞ。

597:デフォルトの名無しさん
08/01/29 23:56:36
全角はチェックしてるって書いてあるだろw

598:デフォルトの名無しさん
08/01/29 23:57:21
まず、LPTSTR を char* にしてコンパイルは通るか?
それをチェックしてみようぜ。

599:デフォルトの名無しさん
08/01/29 23:57:31
うーん、それじゃ、ちょっとソースをあっぷしてみますね

全角半角スペースを表示させても全角はは行っているようにみえないですが…
見落としかもしれないですし

600:デフォルトの名無しさん
08/01/29 23:57:43
あ、いや、wchar_t* か。

601:デフォルトの名無しさん
08/01/29 23:58:03
>>598
あ、はい、分かりました

602:デフォルトの名無しさん
08/01/30 00:01:02
マルチバイト文字セットに変えてchar*型、一応w_char*型にしてみても、
同じエラーが吐かれました(確認したのは大体のエラーの見た目と数だけですが)

ソースをアップする作業に入りますね

603:デフォルトの名無しさん
08/01/30 00:01:27
w_char じゃなくて wchar_t だぜ

604:デフォルトの名無しさん
08/01/30 00:17:01
お待たせしました。
URLリンク(www.youlost.mine.nu)
の、2968.zipです。

うp用に、配置しなおしたら、エラーが増えて涙目になってました(汗
他のアプリケーション用に書いてたものを、エラーはかれていたソースファイルを別プロジェクトでテストしながらなおそうとしたため、
プロジェクト別フォルダから読み込む方式になっています。
ヘッダがプロジェクトに入っていないのは、…えー、ごめんなさい、忘れました、試行錯誤の過程です。
いずれヘッダも戻すつもりではいました。
…ごめんなさい。

605:デフォルトの名無しさん
08/01/30 00:28:00
zantei の最後にセミコロンがない。

606:デフォルトの名無しさん
08/01/30 00:29:01
game.h の方のやつね。

607:デフォルトの名無しさん
08/01/30 00:31:11
「最大50文字で自然数を2つ入力し、その大小を求めるプログラムを作成せよ」
って問題なんですが、プログラム作ってみたけどわかりません
文字数が同じときの結果がめちゃくちゃになりました
誰かこのおしえてください(><)
cout << "文字数a:" << a_count << endl ;
cout << "文字数b:" << b_count << endl ;
if(a_count > b_count){
cout << "a>b" << endl ;
}else if(a_count < b_count){
cout << "a<b" << endl ;
}else if(a_count == b_count){
cout << "文字数が一緒なので一桁ずつ判断します" << endl ;
for(int i=0 ; i < a_count ; i++){
if(a[a_count-i] == b[a_count-i]){
cout << a[a_count-i] << "=" << b[a_count-i] << endl ;
}else if(a[Max_Length-i] != b[Max_Length-i]){
break ;
}
}
if(a[a_count-i] > b[a_count-i]){
cout << "a>b" << endl ;
}else if(a[a_count-i] < b[a_count-i]){
cout << "a<b" << endl ;
}
}
}

608:デフォルトの名無しさん
08/01/30 00:32:38
a[a_count-i-1]

609:デフォルトの名無しさん
08/01/30 00:33:17
(><)

610:607
08/01/30 00:34:08
#include <iostream.h>
#include <iomanip.h>
const int Max_Length = 50 ; // 入力できる文字数の最大値
main()
{
char a[Max_Length] ; // 最初に入力する文字列
char b[Max_Length] ; // あとに入力する文字列
cout << "2つの自然数(最大50桁)を入力し、" << endl ;
cout << "その2数の大小を判定するプログラムです" << endl ;
cout << "数値を入力してください(最大50桁)" << endl ;
cout << "a>>" ;
cin.getline( a , Max_Length ) ;
cout << "b>>" ;
cin.getline( b , Max_Length ) ;
int a_count , b_count ; // 文字カウンタ
int i , j ;
a_count = 0 ;
b_count = 0 ;
i = 0 ;
j = 0 ;
// 文字数をカウントする
while(a[i] != '\n' && a[i] != '\0'){
a_count++ ;
i++ ;
}
while(b[j] != '\n' && b[j] != '\0'){
b_count++ ;
j++ ;
}

611:デフォルトの名無しさん
08/01/30 00:34:14
iostreamマジ見にくい

612:607
08/01/30 00:35:02
610が先で、607が続きです(><)

613:デフォルトの名無しさん
08/01/30 00:35:21
入力できる文字数の最大値が 50 なら、バッファは 51 以上必要だね。

614:デフォルトの名無しさん
08/01/30 00:40:17
std::lexical_compare使え

615:デフォルトの名無しさん
08/01/30 00:44:48
すみません、元からこんなに早くリアクションがくれると思っていなかったので、
質問してすぐ風呂に入る予定だったため、
アップロードしてしばらく返事がなかったので、急いでお風呂に入っていたため、反応が遅れました。
申し訳ありません。

>>605-606
ありがとうございます!

セミコロンを直し、game.hをプロジェクトを追加し、gamemain.cppにgame.hをインクルードし、
gamemain.cppのクラス宣言部分をコメントアウトしてコンパイルしましたが、
結局
error C2146: 構文エラー : ';' が、識別子 'Type' の前に必要です。
がヘッダで吐かれてしまっています…
ここの部分を改善する、考えられるミスはありませんでしょうか…

616:デフォルトの名無しさん
08/01/30 00:50:24
>>607
ヘッダファイルは <iostream.h> や <iomanip.h> ではなく
<iostream> や <iomanip> を使用する事が推奨されている。
cout とかが std::cout とかになっちゃうのが嫌なら、
この程度のプログラムなら using namespace std; と書いておけば std:: を略せる。
古いコンパイラなら知らんがね。

最大 50 文字なら、a のサイズは Max_Length + 1 にする。

cout の後 cin をする際には、cout を flush した方がいい。
cout << "a>>" << flush;
でないと、表示されない事もある。

getline は改行文字を格納しない。改行との比較は無駄。
50 文字以上入力したら次の cin.getline が失敗するのは無視してもいいのかな。宿題程度なら。
cin.clear(); して、改行まで読み飛ばすか構わず cin.getline するか・・・。

文字数カウントは strlen で可能だが、まだ習ってないのかな。
i と j という変数を作らなくても、直接 a_count と b_count 使えばいい。
while 文より for 文使った方がすっきりする。

i が 0 ~ a_count - 1 のループでは、
a_count - i は a_count ~ 1 になる。
これは意図する所ではないはず。
そして、a[Max_Length-i] != b[Max_Length-i] で何をやろうとしているのか分からないし、
このあたり全体的にちとおかしいと思う。
もうちょっとよく考えよう。

617:デフォルトの名無しさん
08/01/30 00:51:00
>>615
TCHAR.h → tchar.h

618:デフォルトの名無しさん
08/01/30 00:51:46
全角だろ。間違いない。全角なんだ。

619:デフォルトの名無しさん
08/01/30 00:53:17
>>615
風呂の予定なんかどうでもいい。
しかも二回も風呂って書きやがって。
風呂はゆっくり入れ。


620:デフォルトの名無しさん
08/01/30 00:54:03
インクルードガードがないのもすげー気になるが、
これだけのヘッダファイルだと BOOL は定義されてなくね?

621:デフォルトの名無しさん
08/01/30 00:54:56
#include <cstddef>
#include <tchar.h>

622:デフォルトの名無しさん
08/01/30 00:55:17
>>616
たくさんありがとうございます!
考え直してもういっかい来ます

623:デフォルトの名無しさん
08/01/30 00:58:12
>>615
とりあえず windows.h をインクルードしとけ。

624:デフォルトの名無しさん
08/01/30 00:58:29
#include <iostream>

int main(void)
{
    const int max_str = 50 + 1;
    char str1[max_str], str2[max_str];    
    std::cout << "数値a入力>";
    std::cin >> str1;
    std::cout << "数値b入力>";
    std::cin >> str2;

    int len1, len2;
    for( len1 = 0; len1 < max_str; ++len1 ){
        if( str1[len1] == '\0' )
            break;
    }
    for( len2 = 0; len2 < max_str; ++len2 ){
        if( str2[len2] == '\0' )
            break;
    }


625:デフォルトの名無しさん
08/01/30 00:59:29
    std::cout << "数値a 文字数:" << len1 << std::endl;
    std::cout << "数値b 文字数:" << len2 << std::endl;
    if( len1 == len2 ){
        std::cout << "文字数が一緒なので一桁ずつ判断します" << std::endl;        
        for( int i = 0; i < max_str; ++i ){
            if( str1[i] == str2[i] )
                continue;
            else if( str1[i] > str2[i] )
                std::cout << "a > b" << std::endl;
            else
                std::cout << "a < b" << std::endl;                
            break;
        }
    }else if( len1 > len2 )
        std::cout << "a > b" << std::endl;
    else
        std::cout << "a < b" << std::endl;

}

>>612
総書き直しすれば簡単

626:デフォルトの名無しさん
08/01/30 00:59:38
>>617
提案ありがとうございます。すみません、でもとおりませんでした
>>618
エディタでトリプルチェックしましたが、やはり全角はありませんでした…
>>619
う…(苦笑)。すみません、お気遣いありがとうです。
>>620
windows.hをインクルードすれば定義されるでしょうか?
>>621
これは、BOOLのヘッダでしょうか。すみません、レスを先にして、試してきます。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch