パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

「情報処理」教員免許の試験問題」記事へのコメント

  • by Anonymous Coward
    何かが間違ってるんですか?
    今リアルタイムで大学でCをやってるものですが・・・
    void main(void)
    むむむ、、、
    • by Anonymous Coward
      皆さん、返答ありがとうございます。

      どうやら私が今習ってるCは相当おかしいみたいで・・・

      前に課題を出されたのですが
      それの解答がこれです。
      http://www.geocities.co.jp/Playtown-Dice/5199/kadai13.txt [geocities.co.jp]

      ここを見てる
      • これって「模範回答」なのでしょうか? ま,突っ込んでみましょう :-)

        • main() の戻り値は色々議論されている通り
        • scanf() の戻り値はチェックしましょう
          入力される数値の数が 3 個よりも少ない場合もあり得ます.
        • a=0, b≠0 のとき,どーなるの?
          判別式自体は正の値なので,解の公式を計算しようとしますが,分母が 0 になるので,「0 で割り算できないぞ」例外で異常終了してしまいます.
        • 解の公式の√の中身は判別式で計算済みなので,こいつを使った方がいいのではないかなぁ.
          同じ内容が繰り返し何度も出てくるのは,「駄目なプログラム」の典
        • by Anonymous Coward
          なんかいろいろ書かれていますが、2次方程式の解を求める際、
              x1 = - b - sqrt(D) if b > 0
              x1 = - b + sqrt(D) otherwise
          としてx2は解と係数の関係を使って決める、という"常識"が指摘されていないのはいかがなものか、と思います。
          • b と sqrt(D) の絶対値が近い場合の桁落ちを防ぐ工夫ですね. 参考になります.

            もう片方の解は c/(x1*a) で求まるので,この場合,生じるのは丸め誤差だけかな.

            ええと,一応説明しておくと,桁落ち,というのは,たとえばこんな感じ.

            1.2345678??? - 1.2345667??? = 0.0000011???
            この例では,有効数字 8 桁の 2 つの数の引き算を行った結果得られる数値の有効数字が 2 桁になってしまってますね. このように絶対値が近い数で引き算を行うと,有効数字の桁数が減ってしまう現象が起きます. これが桁落ち.

            今の2次方程式の解の公式の例では,±√ の2つの解の片方は異符号の演算なので桁落ちの条件に引っかかりますが,もう片方は同符号の演算なので,桁落ちは発生しません. まず,この桁落ちしない方の解を採用し,もう片方の解は上記の式で導きます. この場合は乗除算だけで,丸め誤差の発生がありますが,どのみち丸めが発生するのは有効桁より下なので,有効桁数の現象は生じない,ということになります.

            というところでよろしいでしょうか,先生.

            親コメント
            • by oku (4610) on 2001年12月29日 16時09分 (#50787) 日記
              このテのコードの世界から遠ざかってかなり経つので自信がありませんが、下記に取り込んでみました。
              叩いて下さい > 識者
              #include <stdio.h>
              #include <limits.h>
              #include <math.h>
              #include <float.h>

              int main(void)
              {
                  char s[LINE_MAX];
                  double a, b, c;
                  int sign_of_b;
                  double d;

                  do
                  {
                      fputs("A、B、Cの数値を入力してください。", stdout);
                      fgets(s, LINE_MAX, stdin);
                  }
                  while (sscanf(s, "%lf%lf%lf", &a, &b, &c) != 3);

                  if (-DBL_MIN < a && a < DBL_MIN)
                  {
                      fputs("一次方程式\n", stdout);
                      return 1;
                  }

                  if (b < 0.0)
                  {
                      sign_of_b = -1;
                      b = -b;
                  }
                  else
                  {
                      sign_of_b = 1;
                  }

                  d = b * b - 4.0 * a * c;
                  if (d > DBL_MIN)
                  {
                      double sqrt_d = sqrt(d);
                      double x = -sign_of_b * (b + sqrt_d) / 2.0 / a;

                      printf("答え % f\n", x);
                      printf("     % f\n", x + sign_of_b * sqrt_d / a);
                  }
                  else if (d < -DBL_MIN)
                  {
                      fputs("虚数解\n", stdout);
                  }
                  else
                  {
                      fputs("重解\n", stdout);
                  }

                  return 0;
              }
              親コメント
              • by naka64 (4590) on 2001年12月30日 10時34分 (#50873) 日記
                まずはけた落ち対策の補正。

                   ---
                    char s[LINE_MAX];
                    double a, b, c;
                    int sign_of_b;
                   - double d;
                   + double d, sqrt_d, x ;
                   
                    do
                    {
                   ---
                   ---
                    d = b * b - 4.0 * a * c;
                    if (d > DBL_MIN)
                    {
                   - double sqrt_d = sqrt(d);
                   - double x = -sign_of_b * (b + sqrt_d) / 2.0 / a;
                   + sqrt_d = sqrt(d);
                   + x = -sign_of_b * (b + sqrt_d) / 2.0 / a;
                   
                    printf("答え % f\n", x);
                   - printf(" % f\n", x + sign_of_b * sqrt_d / a);
                   + printf(" % f\n", ( c / ( x * a ) ) );
                    }
                    else if (d < -DBL_MIN)
                    {
                   ---

                宣言文の位置は元のところにあってもいいんですけどね。
                親コメント

アレゲは一日にしてならず -- アレゲ見習い

処理中...