2012-06-16 11 views
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 
+0

チャリスとレヴォンの返信ありがとうございます。歳差運動を増やす方法はありますか? – katta

+0

実際にはより多くのディジットを格納するには、任意精度のライブラリが必要です。 Levonが述べるように、あるいはC++の 'std :: setprecision'を使ってもっと多くを表示することができます。 – chris

+0

@chris低レベルのモーター制御コードはQNX組み込みシステム上のCです。私はC++コードのためにそれを念頭に置いています。 – katta

答えて

10

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

、あなたはこれを変更する場合:あなたが出力として

0.087912, 0.087912 

得るでしょう

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

、すなわち、できるだけ早く一方または両方として除算演算/のオペランドのがフロート/倍であり、結果も(即ち、/二重浮動する「昇格」される)であろう。だから私は

x2 = 360.0/4095.0; 

または

x2 = 360.0/4095; 

x2を変更している可能性があり、上記と同じ結果を得ているでしょう。

@chrisで述べたように、ちょうど.を使用するだけでも十分です。精度について上記のあなたの質問を再

:あなたはすでに長いダブルスで作業している

は..私はあなたには、いくつかの特別なライブラリを使用しない限り、内部で何かを変えることができるとは思わないが、あなたは確かに多くの数字を表示することができます。例えば、

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

MORT-ORA-yが私たちを連想させるEDA-QA @最後に

0.087912, 0.08791208791208791895 

を得られますが、あなたはまた、は、特定の種類に値をキャストすることができますが、それはときを重要あなたはそれを行う。簡単な例(vfloatあるので、値が後floatいずれの場合に割り当てとして終わることに注意):

内蔵同じタイプのオブジェクト上のオペレータの作業
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. */ 
+0

最後のドットだけで十分です。 – chris

+0

@chrisありがとう..私はそれを知りませんでした。何か新しいことを学んだ:)私は答えにこれを追加します。 – Levon

+0

私は新しいことも学びました。おかげです。 – katta

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