3

摂氏を華氏に変換するプログラムを C で作成する場合、次の式では正しくない出力が得られます。

    int fahr = 9 / 5 * celsius + 32;

これはおそらく 9/5 が整数として解釈される問題であることは理解していますが、理解できないのは、doubleまたはを使用しfloatても同じ誤った出力が得られることです。

奇妙なことに、タイプを に設定しているにもかかわらず、次の式は正しい出力を提供しますint

int fahr = celsius / 5 * 9 + 32;

さらに、タイプが に設定されているdouble場合でも、以下のような単純なものでも、1.8 ではなく 1.0 として出力されることに気付きました。

 double x = 9 / 5;
 printf("%lf\n", x);

私はこのスレッドを読みました:

華氏を摂氏に変換する C プログラム

int fahr = celsius / 5 * 9 + 32;しかし、なぜ機能するのかまだわかりませんが、そうではありませんint fahr = 9/5 * celsius+32;か?

4

3 に答える 3

8

あなたは整数で数学をやっています。この式:

9 / 5

C で生成されます。 or1を使用したと言うときは、おそらく の型を変更しただけで、 assignemtn演算子の右側で行われる操作には何もしません。適切な動作を得るには、これらの定数の少なくとも 1 つを a にする必要もあります。doublefloatfahrdouble

9.0 / 5

同様に、このステートメントでは:

double x = 9 / 5;

あなたはまだ整数計算を行っており、その結果をdouble変数に代入しています。他に何も起こっていません。次のいずれかを実行すると、正しい答えが得られます。

double x = 9.0 / 5;
double x = 9 / 5.0;
double x = 9.0 / 5.0;

この表現の理由:

int fahr = celsius / 5 * 9 + 32;

動作するように見えるのは、演算の順序だけです。ここでは、定数演算を最初に行うのではなく、入力を 5 で割ってから 9 を掛けます。次のようにすると、より正確な回答が得られます。

int fahr = celsius * 9 / 5 + 32;

それに加えて、次の式で浮動小数点演算を行うこともできます。

int fahr = celsius * 9.0 / 5 + 32;

整数を使用して元の計算を行いたい場合は、確かにできます。除算する前に乗算するだけです。

int fahr = 9 * celsius / 5 + 32;

この式は、上記で使用されている式のいずれかと同等です。

于 2013-04-18T00:33:16.913 に答える
1

各式または部分式の型は、(ほとんどの場合) 出現するコンテキストに関係なく評価されます。

この宣言では:

double x = 9 / 5;

初期化式は次のとおりです9 / 5。2 つのint式と除算演算子で構成されます。のオペランドは/intであるため、int除算であり、結果はint値になります。整数除算は切り捨てられるため、結果は1、型の になりintます。

その式の結果は、初期化に使用されますxxは 型であるため、値は からにdouble暗黙的に変換され、値が保持されます。intdoublex1.0

xの値を にしたい場合は、1.8浮動小数点除算を行う必要があります。つまり、浮動小数点オペランドが必要です。これを行う最も簡単で明確な方法は次のとおりです。

double x = 9.0 / 5.0;

他にもいくつかの(私見ではあまり明確ではない)アプローチがあります。演算子に typeと/type の 2 つのオペランドがある場合、オペランドは に昇格されるため、これらのいずれも に設定されます。intdoubleintdoublex1.8

double x = 9.0 / 5;
/* or */
double x = 9 / 5.0;

ただし、このアプローチには注意してください。

double y = 9 / 5 / 3.0;

これは次と同等です。

double y = (9 / 5) / 3.0;

これは、yielding9 / 5として計算し、その結果を に昇格させ、 で割ります。int1double3.00.333333333

重要なのは、式のコンテキストが式またはそのオペランドに型を課さないことです。式は分離されているかのように評価され結果はそのコンテキストに応じて変換される場合があります。

于 2013-04-18T00:37:08.357 に答える
1

なぜint fahr = celsius / 5 * 9 + 32;機能するのかはまだわかりませんが、そうではありませんint fahr = 9/5 * celsius+32;

前者の場合、おそらくcelsiusafloatまたは a として宣言しdouble、右側全体をそのように評価します。を使用したと仮定すると、次floatのようになります。

celsius / 5 * 9 + 32
(celsius / 5.0) * 9 + 32
(celsius / 5.0 * 9.0) + 32
(celsius / 5.0 * 9.0 + 32.0)

後者の場合、残りの計算が浮動小数点として発生する前に9/5評価される整数演算です。1この場合:

9 / 5 * celsius + 32
1 * celsius + 32 // Because of this, you get an incorrect answer
celsius + 32
celsius + 32.0

左辺の型は無関係であることに注意してください。右辺はそれに関係なく評価されます。

更新:celsiusは であると言いましたint。これは、たまたま幸運にも の倍数である値をテストして、ステートメントの残りの部分で有効な整数演算を行う前に5正しい整数結果が得られたことを意味します。celsius / 52番目の例では、の倍数である5ことは役に立ちません。

いずれにせよ、なぜ運が良かったのかがわかりましたが、リンクされた質問は、 がcelsiusの倍数ではない場合に機能する数式を得るために実際に必要なことに対する答えを提供します5。そこにある答えの。

于 2013-04-18T00:37:34.500 に答える