6

x2 がゼロを出力する理由を誰でも教えてくれますか? 浮動小数点表現 X1 が丸められているため、歳差運動を維持する方法があると思います。

long double x1, x2;
x1= 0.087912088; // Note: 360/4095 = 0.087912088
x2 = 360/4095;
printf("%Lf, %Lf \n",x1, x2);

結果:

x1 =0.087912
x2= 0.000000
4

2 に答える 2

10

問題は整数の切り捨てです..2つの整数を除算しています=>結果は、小数部分が捨てられた別の整数になります。(たとえば、整数除算の実際の結果が 3.9 の場合、切り捨てにより 3 になります (つまり、丸められません))。

あなたの場合、これを次のように変更すると:

x2 = 360 / 4095.0;  /* one of the operands now has a decimal point */

あなたが得るでしょう

0.087912, 0.087912 

出力として。

つまり、除算演算子のオペランドの一方または両方が float/double になるとすぐ/に、結果も同様になります (つまり、float/double に「昇格」されます)。だから私はに変更x2することができた

x2 = 360.0 / 4095.0;

また

x2 = 360.0 / 4095;

上記と同じ結果が得られます。

@chris が述べたように、 a を使用する.だけでも十分です。

精度に関する上記の質問について:

あなたはすでに long double で作業しています..特別なライブラリを使用しない限り、内部的には何も変更できないと思いますが、より多くの数字を表示することは確かにできます。例えば、

  printf("%Lf, %.20Lf \n",x1, x2); 

譲ります

  0.087912, 0.08791208791208791895 

最後に、@edA-qa mort-ora-y が思い出させてくれるように、値を特定の型にキャストすることもできますが、それはいつ行うかが重要です。簡単な例 (が a であるため、代入float の値は最終的に次のようになることに注意してください):vfloat

float v = 0;
                     /* values shown are BEFORE assignment */
v = (5 / 2);         /* value is 2 due to integer truncation before assignment */
v = (float) (5 / 2); /* 2.0 as integer division occurs 1st, then cast to float */
v = (float) 5 / 2;   /* 2.5 since 5 becomes 5.0 through casting first. */
于 2012-06-16T02:22:26.967 に答える
3

組み込み演算子は、同じ型のオブジェクトで機能します。結果はパラメータと同じ型です。この場合、除算は 2 つの整数に対して行われるため、結果は整数になります。

x2 = 360/4096;
//   int/int  = int

したがって、0の結果が期待されます。

組み込み型の演算子が異なる場合、それらは同じ型になるように昇格されます (結果もその型になります)。だからあなたが欲しいのは:

x2 = 1.0 * 360/4095;  // or 360.0/4095

// This is
    double * int / int

==> (double * double)/int
==> (double * double)/double
于 2012-06-16T02:28:13.230 に答える