今回も (C 流の scanf() & printf() ではなくて) ストリームを使って入出力をする。 ここで一つの困難が出現する。 数値計算プログラミングでは、結果を数値で出力する際に、 書式の指定をすることが必須であるが、 C++ で書式の指定をするのは思いの外面倒である。 C では %20.15f だけで済むことを一体どうやるのか、 以下のサンプル・プログラムを見てもらいたい。 世の中には、この理由から、C++ でプログラムを書く場合にも、 ストリームではなくて printf() を使って結果を出力する、 という人が結構いたようである。
(なお、「§3.10 入出力の書式 (とりあえずの例)」 も見よ。そちらの方が書いたのが新しい。)
(C の場合については、 「C言語これくらい覚えよう §3.4 浮動小数点数の入出力と四則演算」 を見よ。)
quadratic_eq.cpp |
/* * quadratic_eq.cpp */ #include <iostream> #include <iomanip> #include <cmath> using namespace std; int main(void) { double a,b,c,D; cout << setprecision(15); cout.setf(ios::fixed, ios::floatfield); cout << "a,b,c: "; cin >> a >> b >> c; D = b * b - 4 * a * c; if (D >= 0) cout << setw(20) << (-b+sqrt(D))/(2*a) << ", " << setw(20) << (-b-sqrt(D))/(2*a) << endl; else cout << setw(20) << -b/(2*a) << "±" << setw(20) << sqrt(-D)/(2*a) << " i" << endl; return 0; } |
コンパイルと実行結果 |
oyabun% g++ -o quadratic_eq quadratic_eq.cpp oyabun% ./quadratic_eq a,b,c: 1 2 1 -1.000000000000000, -1.000000000000000 oyabun% ./quadratic_eq a,b,c: 1 1 1 -0.500000000000000± 0.866025403784439 i oyabun% |
cout.setf(ios::fixed, ios::floatfield); | 小数形式 |
cout.setf(ios::scientific, ios::floatfield); | 指数形式 |
cout << resetiosflags(ios::floatfield); | 元に戻す |
率直に言って、 C++ のこのあたりの機能を設計した人間は馬鹿だったのだと思う。
(…乱暴なことを言うようだけれど、このせいで多くの人達に無用の混乱を与えて、 長い時間を浪費させていると思っている。C言語のやり方は、 Fortranのやり方を踏襲したもので、うまいやり方ではないけれど、 ほどほどの使い勝手だと思われる。)
参考: https://www.horstmann.com/ にある “The March of Progress”
1980: C |
printf("%10.2f", x); |
1988: C++ |
cout << setw(10) << setprecision(2) << fixed << x; |
1996: Java |
java.text.NumberFormat formatter = java.text.NumberFormat.getNumberInstance(); formatter.setMinimumFractionDigits(2); formatter.setMaximumFractionDigits(2); String s = formatter.format(x); for (int i = s.length(); i < 10; i++) System.out.print(' '); System.out.print(s); |
2004: Java |
System.out.printf("%10.2f", x); |
(皮肉の説明をするのは無粋かもしれないけれど) Horstmann 先生の言いたいことは、 古い C で簡潔に出来ていたことが、 それから後に出た C++ や Java でどんどん複雑になって行った。 大した進歩だこと。 結局 2004年の Java では、C風のやり方が使えるようになった。 それ見たことか (最初からそうすれば良いのに)、ということだろう。
(2024/9/10追記) 久しぶりにアクセス。サイトなくなっていないかしら(どきどき)。 あった、あった。続きも書いてありました(笑)。