1 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 06:24:18 ] C言語の入門者向け解説スレです。 ・C++言語はスレ違いです。 ・分からない事をなるべく詳しく書いて下さい。 ・ソースコードを晒すと答えやすくなるかもしれません。 ・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。 前スレ C言語なら俺に聞け(入門篇) Part 20 pc11.2ch.net/test/read.cgi/tech/1192455273/ 教えて欲しいのではなく丸投げしたいならこちらへ C/C++の宿題を片付けます 99代目 pc11.2ch.net/test/read.cgi/tech/1194262698/
593 名前:デフォルトの名無しさん [2007/11/22(木) 15:05:40 ] 計ってみたよ 配列に何度も入れた方がわずかに速いようだ #include <iostream> #include <time.h> #define N 900000 using namespace std; main(){ unsigned int n,k,c,sum; unsigned int *x,*y,*z,*v,*w; x=new unsigned int [N]; y=new unsigned int [N]; z=new unsigned int [N]; v=new unsigned int [N]; w=new unsigned int [N]; for(n=0;n<N;n++){x[n]=rand()%10;y[n]=rand()%N;z[n]=rand()%N;v[n]=rand()%N;w[n]=rand()%N;} sum=0; c=clock(); for(n=0;n<N;n++){k=w[n];k=v[k];k=z[k];k=y[k];sum+=x[k];} c=clock()-c; cout<<c<<" clock "<<sum<<endl; sum=0; c=clock(); for(n=0;n<N;n++)sum+=x[y[z[v[w[n]]]]]; c=clock()-c; cout<<c<<" clock "<<sum<<endl; }
594 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:30:37 ] >>593 手元のiccでは全く同じコードにコンパイルされたよ。 -- movl (%rbx,%rcx,4), %ecx #15.20 movl (%rbp,%rcx,4), %edi #15.27 movl (%r12,%rdi,4), %r8d #15.34 movl (%r13,%r8,4), %r9d #15.41 addl $1, %edx #15.13 movl %edx, %ecx #15.13 addl (%r10,%r9,4), %r15d #15.46 movl %ecx, %edx #15.1 cmpl $900000, %edx #15.1 jb ..B1.15 # Prob 99% #15.1 -- movl (%rbx,%rcx,4), %ecx #19.30 movl (%rbp,%rcx,4), %esi #19.28 movl (%r12,%rsi,4), %edi #19.26 movl (%r13,%rdi,4), %r8d #19.24 addl $1, %edx #19.13 movl %edx, %ecx #19.13 addl (%r9,%r8,4), %r15d #19.17 movl %ecx, %edx #19.1 cmpl $900000, %edx #19.1 jb ..B1.23 # Prob 99% #19.1 --
595 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:31:30 ] 処で、>593はなんでC++でコンパイルしているんだ?
596 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:34:55 ] 仮想関数を利用する上での注意点があれば教えて下さい。
597 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:40:00 ] iccだとmovlにしてくれるのか VCだとmov,mov,...ってのにしかならない
598 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:44:40 ] >593以下速度の話題 C/C++スレか速度スレ、或いは最適化スレへどうぞ。 >>596 あんたもスレ違い。
599 名前:デフォルトの名無しさん [2007/11/22(木) 21:02:53 ] for(i=10;i>=0;i--)printf("%d\n"i); っていうコード unsigned にするとやばいね 全然気づかなかったよ
600 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 21:11:23 ] 処理系依存になるってこと?
601 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 21:17:31 ] unsigned int iに対してi>=0は常に真だべ
602 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 21:20:46 ] なるほど どうもありがとう
603 名前:デフォルトの名無しさん [2007/11/22(木) 22:37:22 ] ポインタが指してる内容を配列に入れたいのですがどうしたらいいですか? 例えば、 char *a="ABC"; char b[4]; このとき、 b[0]=A,b[1]=B,b[2]=C にしたいです。
604 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 22:39:15 ] strcpy(b,a);
605 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 22:41:18 ] memmove(b,a,3);
606 名前:603 mailto:sage [2007/11/22(木) 23:01:19 ] >>604 ,>>605 できました。 ありがとうございます。
607 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:01:27 ] for(i=0;b[i]=a[i];i++);
608 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:16:00 ] 昨日自己参照構造体でのリストについてかけねーって嘆いてた者だけど、 今日紙に書きつつ、これがこーなるから次はこうなるだろーってソース書いてったら無事動きました!
609 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:28:12 ] 二次方程式の解の公式を求めるプログラムを作れとの課題が出たので考えてみたのですが 思うようにうまくいきません。 #include <stdio.h> #include <math.h> int main() { double x1 ,x2, a, b, c; printf( "a = " ); scanf("%lf" , &a); printf( "b = " ); scanf("%lf" , &b); printf( "c = " ); scanf("%lf" , &c); x1 = -b+sqrt(b*b-4.0*a*c)/2.0*a; x2 = -b-sqrt(b*b-4.0*a*c)/2.0*a; printf("x1= %lf x2= %lf\n", x1, x2); } までできたのですが、 x1= -1.#IND00 x2= -1.#IND00 何を入力してもこの答えになってしまいます。 自分なりに見直してみたのですが間違いが分かりません。 どなたかご教示いただけたら幸いです。
610 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:32:03 ] そもそも式が違うじゃん
611 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:39:05 ] かけざんとわりざんはたしざんやひきざんよりもさきにけいさんします。
612 名前:609 mailto:sage [2007/11/22(木) 23:40:33 ] 式からして間違ってるのでしょうか? 今の式じゃ-bがが最後に計算されてしまうってことですかね?
613 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:43:51 ] >>609 あなたが書いている式は √(b^2 - 4ac) x1 = -b + ------------- * a 2 こんなだよ
614 名前:609 mailto:sage [2007/11/22(木) 23:44:12 ] x1 = (-b+sqrt(b*b-4.0*a*c))/2.0*a; x2 = (-b-sqrt(b*b-4.0*a*c))/2.0*a; こんな感じでいいんでしょうか?あと warning C4996: 'scanf' が古い形式として宣言されました。 というエラーが発生してるんですがこれが原因でしょうか? 習ったとおりに書いてみたのですが。
615 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:46:11 ] printfで%lfは標準じゃなかった気がする。 独自拡張とかC99とかならいけたかもしれんけど。
616 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:47:57 ] >>613 最後のaは分母にかかりますよね? >>615 そうなんですか・・・家と学校じゃ環境が違うのでそのせいかもしれません。 他に間違ってるところありますかね?
617 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:09 ] >>614 それは警告であってエラーじゃない
618 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:11 ] >>614 (...)/2*aじゃなくて(...)/(2*a)
619 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:15 ] それだと -b + √(b^2 - 4ac) x1 = ----------------- * a 2 だな >warning C4996: 'scanf' が古い形式として宣言されました。 warning C4996 でぐぐれ
620 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:46 ] >>616 かからねーよwww
621 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:51:39 ] >>618-620 なるほど・・・()付けない限り数字同士はくっ付かないんですか ご指摘ありがとうございます。修正してみましたが、相変わらず答えは変わりません。 他に間違っているところがないのであれば家の環境が悪いということで諦めます。
622 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:53:55 ] 入力してる値が悪いのでは?実数解を持つ値を入れてみ
623 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:59:22 ] >>622 答えがでました。適当に値を入れていたのが原因でしたか・・・ こんな基礎の問題に答えてくれて助かりました。 もっと勉強しないと駄目なようです、ありがとうございました。
624 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:02:47 ] 適当にいれんなよwwwwwwwwwwww
625 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:05:03 ] Cに一番大事なのはとにかく基礎。 応用なんてものは後回しでとにかく基礎だぜ。
626 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:06:46 ] AもBもすっとばしていきなりCやるとはたかれるってことですよねー
627 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:11:14 ] たまにする背伸びは楽しいけどな 良い気分転換になる
628 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:12:09 ] fizzbuzzもかけない段階でchaos pp使ってメタプログラミングしたりな
629 名前:助けてBOYZ [2007/11/23(金) 02:27:55 ] 今日からの連休中に3つの課題を出されました。 ポインタ大嫌いです。 どなたか助けて下さい。 この問題が一つ目です。 【問】数字文字列を数値化する関数を作成して下さい。 <関数仕様> 書式 :short *AtoS(char *pStr, int *pRetCode); 戻り値:数字文字列のポインタ 引数 :char *pStr → 文字列の先頭アドレス :int *pRetCode → 動作の成否を返す (正常なら:0,エラー時は-1) ※但し、NULLの時は返さない 処理 :pStrで与えられた文字列をshort型の数値に変換する ※負数(マイナス)にも対応 <考慮必要事項> ・short型の範囲外の数値文字列 ・非数字文字列 ・数字文字列と非数字文字列の混在(先頭の'-')は除く ・空文字列 ・NULL 以上の5つはpRetCodeの示す領域にはエラーを返す、戻り値は0
630 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 02:28:53 ] >>629 いつまで逃げ続けられるの? 終わりはあるの?
631 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 02:40:04 ] >>629 自分で考える気がないなら宿題スレへ pc11.2ch.net/test/read.cgi/tech/1195668114/
632 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:03:04 ] >>609 printf("x1= %f x2= %f\n", x1, x2); で試したのか? どうみてこうだと思うんだが
633 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:05:05 ] >>632 そういう問題じゃないから
634 名前:助けてBOYZ [2007/11/23(金) 03:11:41 ] 何とか自分で作ってみました。 だけど戻り値?とか関数の意味がよく分からないし、何だかグダグダと 長いプログラムになってしまいました。 ポインタ&関数を理解するコツを教えて下さい。
635 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:15:18 ] 戻り値ってshort*なの?
636 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:15:18 ] そもそも問題がおかしいのにどうしろと 文字列を数値化するのに文字列へのポインタ返してどうしろと
637 名前:助けてBOYZ [2007/11/23(金) 03:22:30 ] 戻り値はshortみたいです。 一応表示はされたんですけど… ちょっとチェックして下さい。 おかしいところ教えて下さい。
638 名前:助けてBOYZ [2007/11/23(金) 03:26:42 ] #include <stdio.h> short AtoS(char *pStr, int *pRetCode); int main(void) { short val; int ret = 0; val = AtoS("1234", &ret); printf("%d\n", val); val = AtoS("-789", &ret); printf("%d\n", val); val = AtoS("atai", &ret); if (-1 == ret) { printf("数値文字列でないデータが渡されました。\n"); } return 0;
639 名前:助けてBOYZ [2007/11/23(金) 03:27:56 ] 改行が多くて入りませんでした。 間違ってるところあれば教えて下さい。 short AtoS(char *pStr, int *pRetCode) { int *p; int i; int sum; short goukei; goukei = 0; if (pStr[0] == '-') { for (i = 1; pStr[i] != '\0'; i++) { /* p[0]に'-'が入力された */ pStr[i] = pStr[i] - '0'; goukei = pStr[i] + (goukei * 10); } goukei = goukei - (goukei * 2); return goukei; } goukei = 0; for (i = 0; pStr[i] != '\0'; i++) { /* p[0]〜'\0'の中に数字だけが入力された */ if (pStr[i] > 48 && pStr[i] < 58) { pStr[i] = pStr[i] - '0'; goukei = pStr[i] + (goukei * 10); } else { *pRetCode = -1; return pRetCode[0]; } } return goukei;
640 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 05:10:13 ] >>629 次からは宿題スレへ #include <stdio.h> short AtoS(char *pStr, int *pRetCode) { int n,s; if(pRetCode == NULL) return 0; *pRetCode = -1; if(pStr == NULL || *pStr == '\0') return 0; for(s=*pStr=='-'?1:0,pStr+=s,n=0;*pStr != '\0' && *pStr>='0' && *pStr<='9';pStr++) n=n*10+*pStr-'0'; n=s==1?-n:n; if(*pStr != '\0' || *(pStr-1) == '-' || n<-32768 || n>32767) return 0; *pRetCode = 0; return n; } int main() { int i,s,r; char t[][8]={"","-","a","-a","a1","1a","1-", "-32769","-32768","-1","0","1","32767","32768","-000001","000001"}; printf("String\t: Value\t(RetCode)\n"); s = AtoS("1",NULL); printf("\"1\"\t: %d\t(NULL)\n",s); s = AtoS(NULL,&r); printf("(NULL)\t: %d\t(%d)\n",s,r); for(i=0; i<sizeof(t)/8; i++) { s = AtoS(t[i],&r); printf("\"%s\"\t: %d\t(%d)\n",t[i],s,r); } return 0; }
641 名前:640 mailto:sage [2007/11/23(金) 06:31:08 ] 訂正 #include <stdio.h> short AtoS(char *pStr, int *pRetCode) { int n,s; if(pRetCode == NULL) return 0; *pRetCode = -1; if(pStr == NULL || *pStr == '\0') return 0; for(s=*pStr=='-'?1:0,pStr+=s,n=0;*pStr != '\0' && *pStr>='0' && *pStr<='9' && n>=-32768;pStr++) n=n*10-*pStr+'0'; n=s?n:-n; if(*pStr != '\0' || *(pStr-1) == '-' || n<-32768 || n>32767) return 0; *pRetCode = 0; return n; } int main() { int i,s,r; char t[][16]={"","-","a","-a","a1","1a","1-", "-32769","-32768","-1","0","1","32767","32768","-000001","000001","4294967296"}; printf("String\t: Value\t(RetCode)\n"); s = AtoS("1",NULL); printf("\"1\"\t: %d\t(NULL)\n",s); s = AtoS(NULL,&r); printf("(NULL)\t: %d\t(%d)\n",s,r); for(i=0; i<sizeof(t)/16; i++) { s = AtoS(t[i],&r); printf("\"%s\"\t: %d\t(%d)\n",t[i],s,r); } return 0; }
642 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 09:05:09 ] >>639 > pStr[i] = pStr[i] - '0'; 文字列へのポインタ貰った関数が、中身を書き換えちゃいけない。 呼び出し側が、 n=AtoS("12345", &x); とした場合、pStrの指す先は書き換えは不可能である処理系が多い。 普通、こういう文字列へのポインタを貰う関数は、 short AtoS(const char *pStr, int *pRetCode) のようにconstを付ける。
643 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 09:23:18 ] >641 for(s=*pStr=='-'?1:0,pStr+=s,n=0;*pStr != '\0' && *pStr>='0' && *pStr<='9' && n>=-32768;pStr++) n=n*10-*pStr+'0'; ↑こういう可読性の悪い書き方はやめようぜ…
644 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 09:24:47 ] わざとだろう
645 名前:デフォルトの名無しさん [2007/11/23(金) 10:41:36 ] x[n]とr=0.6に対して (x[0]-x[1])/x[1] + r * (x[1]-x[2])/x[2] + r^2 * (x[2]-x[3])/x[3] + ・・・ という計算を多くするとき計算が速く終わるコードって分かりますか? x[n]は変化します 厳密な値ではなくていいです
646 名前:デフォルトの名無しさん [2007/11/23(金) 10:42:45 ] あとx[n]の値は50%以内のずれしかありません
647 名前:デフォルトの名無しさん [2007/11/23(金) 10:54:43 ] x[n]の平均値hとその誤差をd[n]とすると (x[0]-x[1])/x[1] =d[0]-d[1]/x[1] =d[0]-d[1]/h =(d[0]-d[1])*k k=1/h とすれば速そうですね
648 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 11:57:13 ] (x[0]-x[1])/x[1] = x[0]/x[1]-1 でしょ。 -1の部分だけ分けて、 元の式=x[0]/x[1]+r*x[1]/x[2]+r^2*x[2]/x[3]....-(1+r+r^2+...) とすれば、 r=0.6固定なら後ろの部分は定数だから前もって計算しておけば早いのかも。 精度が無視できる項以降は計算しないって手もあるのかな。 有効数字2ケタでいいなら、0.6^10以降は計算しなくてもいいと思う。
649 名前:デフォルトの名無しさん [2007/11/23(金) 12:22:00 ] >>648 サンクス
650 名前:574 mailto:sage [2007/11/23(金) 13:43:42 ] >>576-579 ありがとうございました。 プロトタイプ宣言はやはり暗黙的にexternのですね。 社内のソースと合わせるため、一応これからはグローバルな関数はexternを付けて区別していこうと思います。
651 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 14:22:28 ] プロトタイプ宣言は厳密には暗黙的に extern なのではなくて、 それより前に static なプロトタイプ宣言や関数定義がなければ extern になり、 あれば static になる。
652 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 14:24:28 ] そういうときに「規定」って言葉を使うのかな。
653 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 14:26:23 ] ヘッダファイルで static な関数プロトタイプを書くことは無いし、 ヘッダファイルはファイルの先頭でインクルードするしで、 >>651 のような曖昧さがあっても実際の所これが問題になる事はない。 extern をつけるかどうかは好みの問題。
654 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 15:14:15 ] >>653 すまん。 前2行と後ろ2行の関係が分からん。 出来ればもうちょい詳しく頼む。
655 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 15:39:55 ] 別のスレに翻訳単位をよくわかってない奴がいたな。 ヘッダファイルは彼にとって何か特別なものなのかもしれないが。
656 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 15:52:05 ] >>654 前2行の理由により、普通はヘッダファイル内にあるプロトタイプ宣言より先に static なプロトタイプ宣言や関数定義が現れることはないから、 実質的には暗黙的に extern になると考えても問題ないという話。
657 名前:デフォルトの名無しさん [2007/11/23(金) 19:14:43 ] ここに来てるのってみんなプログラマーなの?
658 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 19:36:03 ] プログラムが出来るって意味ではみんなプログラマーだろうな
659 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 19:59:26 ] 職業=プログラマはあんまいないと思う 学生とSEばっか
660 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 20:09:55 ] いや、プログラマーって普通にいるだろ。
661 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 20:13:13 ] >>659 SEが居るならプログラマも居る事になるんだよ
662 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 20:19:42 ] SEと職業プログラマはちょっと違うけどな
663 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 20:21:40 ] あ、名刺はSEだけどプログラマって人はいっぱいいると思う 特に若い人。
664 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 20:35:16 ] 昔職業プログラマって優れたコードを書く人だと思ってたけど、 なってみたら優れたコードとかは二の次で動くコードを書く人だと知った。
665 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 20:40:15 ] 資格とかいらなくて、基本的にだれでもやれる職業だしな。
666 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:25:12 ] 頭使うドカタだしな。
667 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:44:55 ] 名刺もってるプログラマに出会ったことないんだけど
668 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:46:47 ] 名刺は持ってるぞ 渡す機会は無いけど
669 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:47:29 ] 名刺に「プログラマ」と書くとどうしても低く見られるから、 「システムエンジニア」と書くんだよ。
670 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:48:33 ] みんな普通にもってるでしょ? 自社以外の人にいっさい会わないで、こもって仕事してるならいらないけど。 名詞の肩書きに「プログラマー」とか入ってないって意味?
671 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:50:10 ] 所属とか役職は入ってるけど、プログラマーとかSEとかってのは書いてないよね。
672 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:50:43 ] いや、会社が名刺をつくってくれないらしいんだが……
673 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:54:02 ] たまにしか使わないのに何十枚も刷ると高いから、 使うときに1枚だけプリンタから出せってことだよ。
674 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 21:58:23 ] 数十枚刷れば数年もつ
675 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 22:03:15 ] プログラマが名刺出すような状況にならんだろ SEとして派遣されたら名刺だすけどさ
676 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 22:10:23 ] >672-673 どんだけ貧乏な会社なんだよ。 100枚1000円ぐらいなのに…
677 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 22:11:36 ] 使わないものを作ったってねぇ
678 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 22:15:03 ] あんま名刺出すとセールスの電話が増えて業務が滞る
679 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 23:19:51 ] >>678 わたくしどもはお客様の会社にプログラマを派遣いたしております わたくしどもは常に優秀な人材を取り揃えてございます おたくの会社にもおひとついかがでしょうか?
680 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 23:23:29 ] おもしろくないよ
681 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 23:32:04 ] そのとおり 笑えない話なのさ
682 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 23:47:54 ] Cでpow(5,i)の計算をした時のことでお聞きしたいことがあります。 最初はpow(5,0)=1,pow(5,1)=5,(5,2)=25....と順調です。 しかし、pow(5,23)の時に本来ならば11920928955078125のはずなのですが、 なぜか11920928955078124と1小さい数になってしまいます。 pow(5,24)以降も正しい数値が得られず誤差がどんどん大きくなっていってしまいます この原因が全く分からず途方にくれている状態です…よろしくお願いします。
683 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 23:50:40 ] >>682 ttp://ja.wikipedia.org/wiki/%E8%AA%A4%E5%B7%AE#.E8.A8.88.E7.AE.97.E8.AA.A4.E5.B7.AE.E3.81.AE.E7.A8.AE.E9.A1.9E
684 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 23:51:45 ] >>682 doubleの有効桁数を超えてるとか。
685 名前:デフォルトの名無しさん [2007/11/23(金) 23:57:53 ] 多売長ライブラリ
686 名前:デフォルトの名無しさん mailto:sage [2007/11/24(土) 00:15:23 ] >683 倍精度浮動小数点で普通使われるIEEE 754 形式だと仮数部52ビットだけど、 pow(5,23)で52bitを超えるから、以降は誤差が出る。 誤差を避けるためには自分で作るしかない。 でも多分そういうアルゴリズムは探せばあるよ。
687 名前:デフォルトの名無しさん [2007/11/24(土) 01:53:27 ] 0*0.003=0 をlog計算するためにプログラムでかくにはどうすればいいですかね? 0*確率なら0になるから処理の結果に影響ないんだけど logだと0にならないんで困るわ。
688 名前:デフォルトの名無しさん mailto:sage [2007/11/24(土) 01:54:20 ] ?
689 名前:デフォルトの名無しさん mailto:sage [2007/11/24(土) 02:09:44 ] わからないかな? たとえばこの図であらわすと kossie.net/up/src/kos1247.jpg startから1回目の移動で↑と↓に移動できるそのときの確率が0.5と0.5 start地点の状態確率が1とすると↑と↓に移動した段階の状態確率はそれぞれ0.5 0.5 プログラム的に1回の移動ごとに、すべての状態をまわって、 そのあとに2回目の移動をすることにしてます。そうじゃないと作れないので。 これを小数点でなら最初すべての状態の確率を 0にしておけば、それぞれの移動ごとに すべての状態をまわっても0*移動確率 =0になるので変な数値が値がでることはありません。 ただlogで計算する場合に、logはlog(A*B)=logA+logBという性質があるので Aが0であってもBが0でなければ数値は残ってしまういうわけ。 これでプログラムになやんでるんですよ。
690 名前:デフォルトの名無しさん mailto:sage [2007/11/24(土) 02:13:56 ] そもそもlogxって定義域x>0だろが
691 名前:689 mailto:sage [2007/11/24(土) 02:35:46 ] まあ問題はこういう感じなんですけど、図は>>689 のとおりです いま、start,1,2,3,10,11,endという状態がありまして、 以下のような確率で移動することとします。 最初はstartで最後はendです。startの状態確率は1.0です。 1.0から移動する確率をかけると状態1のその時点での状態確率が0.5、状態2の状態確率が 0.5となります。 ただし状態1は入ってくる矢印が3つですので、その時点では0.5ですが 次の状態に状態1から状態1へ移動すると0.5X0.6の計算をして0.3となるわけで す。この(startから状態1への移動確率) (状態1の状態確率)X(状態1から状態1への移動確率)と、(状態11の状態確率)X(状態11 から状態1への移動確率)の和が状態1の状態確率となります。 startから状態10に移動したり、状態2に移動したりして計算をしていって endにきたときの最終状態確率を求めよ。っていうのが問題です。 これをlogで計算しないといけないっていう前提にプログラムを作るとしたら どうつくっていきますか?ただし状態に入ってくる3つの値は比較しながら 計算しないといけないんでね。logの計算なので。
692 名前:デフォルトの名無しさん mailto:sage [2007/11/24(土) 02:39:14 ] >>689 なんだお前か 氏ね
693 名前:689 mailto:sage [2007/11/24(土) 02:46:15 ] どうせできないのにいばんな。