アカウント名:
パスワード:
これって「模範回答」なのでしょうか? ま,突っ込んでみましょう :-)
b と sqrt(D) の絶対値が近い場合の桁落ちを防ぐ工夫ですね. 参考になります.
もう片方の解は c/(x1*a) で求まるので,この場合,生じるのは丸め誤差だけかな.
ええと,一応説明しておくと,桁落ち,というのは,たとえばこんな感じ.
1.2345678??? - 1.2345667??? = 0.0000011???
今の2次方程式の解の公式の例では,±√ の2つの解の片方は異符号の演算なので桁落ちの条件に引っかかりますが,もう片方は同符号の演算なので,桁落ちは発生しません. まず,この桁落ちしない方の解を採用し,もう片方の解は上記の式で導きます. この場合は乗除算だけで,丸め誤差の発生がありますが,どのみち丸めが発生するのは有効桁より下なので,有効桁数の現象は生じない,ということになります.
というところでよろしいでしょうか,先生.
#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; }
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
アレゲは一日にしてならず -- アレゲ見習い
えっ? (スコア:0)
今リアルタイムで大学でCをやってるものですが・・・
void main(void)
むむむ、、、
Re:えっ? (スコア:0)
どうやら私が今習ってるCは相当おかしいみたいで・・・
前に課題を出されたのですが
それの解答がこれです。
http://www.geocities.co.jp/Playtown-Dice/5199/kadai13.txt [geocities.co.jp]
ここを見てる
Re:えっ? (スコア:1)
これって「模範回答」なのでしょうか? ま,突っ込んでみましょう :-)
入力される数値の数が 3 個よりも少ない場合もあり得ます.
判別式自体は正の値なので,解の公式を計算しようとしますが,分母が 0 になるので,「0 で割り算できないぞ」例外で異常終了してしまいます.
同じ内容が繰り返し何度も出てくるのは,「駄目なプログラム」の典
Re:えっ? (スコア:0)
x1 = - b - sqrt(D) if b > 0
x1 = - b + sqrt(D) otherwise
としてx2は解と係数の関係を使って決める、という"常識"が指摘されていないのはいかがなものか、と思います。
Re:えっ? (スコア:1)
b と sqrt(D) の絶対値が近い場合の桁落ちを防ぐ工夫ですね. 参考になります.
もう片方の解は c/(x1*a) で求まるので,この場合,生じるのは丸め誤差だけかな.
ええと,一応説明しておくと,桁落ち,というのは,たとえばこんな感じ.
この例では,有効数字 8 桁の 2 つの数の引き算を行った結果得られる数値の有効数字が 2 桁になってしまってますね. このように絶対値が近い数で引き算を行うと,有効数字の桁数が減ってしまう現象が起きます. これが桁落ち.今の2次方程式の解の公式の例では,±√ の2つの解の片方は異符号の演算なので桁落ちの条件に引っかかりますが,もう片方は同符号の演算なので,桁落ちは発生しません. まず,この桁落ちしない方の解を採用し,もう片方の解は上記の式で導きます. この場合は乗除算だけで,丸め誤差の発生がありますが,どのみち丸めが発生するのは有効桁より下なので,有効桁数の現象は生じない,ということになります.
というところでよろしいでしょうか,先生.
Re:えっ? (スコア:2)
叩いて下さい > 識者
Re:えっ? (スコア:1)
---
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)
{
---
宣言文の位置は元のところにあってもいいんですけどね。