2016-09-08 16 views
-1

val0.05の最も近い倍数にfloat値を丸めたいとします。私の意図の説明はhereです。私は既にvalの上限と下限を持っています。例えば、それぞれvalUvalLです。私は、次の方法でこれを行うことができます:範囲[valL, valU]0.05の倍数のための浮動小数点数を2小数点以下に丸める

  1. 検索し、それに応じて値を割り当てます。結びつきは、より低い価値を取ることによって解決されます。 OR
  2. thisのようなものを使用します(リンクに記載されているソリューションでは、コースが20で100を置き換えます)。

この方法-2では、何度か間違った結果が得られることがわかります。誰かが私になぜ方法-1が正しいのか教えてもらえますか? binary floating point典型的な考える

+3

方法2が最適です。コードを表示します。 – Barmar

+0

関連資料**はここに**掲載してください。リンクされたデータは参照データのみです。 – chux

答えて

1

... float値を丸める、0.05の最も近い倍数にvalを言う...

、持っていたことができる最高の

...ラウンドでfloatの値を0.05の倍数に最も近い値に設定すると、floatrのように保存されます。


方法1はコーナーケースでは不明です。 OPが持つのはコードではなく、実際のCコードではなく、数学の観点からのコードの概要です。私は#2のバリエーションで動作します。非常にです。 @Barmar

ほとんどの方法2:乗算、ラウンド、次に除算。

#include <math.h> 
double factor = 20.0; 
float val = foo(); 
double_or_float rounded_val = round(val * factor)/factor; 

この方法には2つの微妙な点があり、優れています。

  1. 乗算が参照答えより高い精度と範囲で行われている - これは正確製品と非常正確な商を可能にします。プロダクト/商がfloatの数学だけで計算された場合、いくつかのエッジケースは間違った答えとなり、もちろんいくつかの大きな値は無限にオーバーフローします。

  2. "ネクタイはより低い値をとることによって解決されます。"厳しいと珍しい目標です。選択を歪ませた目標のように聞こえる。 round(double)現在の丸め方向にかかわらず、ハーフウェイの場合をゼロからうまく丸めます。 「下限」を達成するには、現在の丸め方向を変更し、rint()またはnearbyint()を使用します。


#include <fenv.h> 
int current_rounding_direction = fegetround(); 
fesetround(FE_DOWNWARD); 
double rounded_val = rint(val * factor)/factor; 
fesetround(current_rounding_direction); 

...方法-2利回り間違った結果、いくつかの回...

OPコードおよび種々の方法の強/弱の品質説明のために使用され、計算正確値を投稿する必要があります。試してくださいprintf("%a %a\n", val, rounded_val);。使用にprintf("%f\n", val);

さらに

をコーディングする必要があり、多くの場合、問題は、使用される正確な値の不正確な理解に発生した:「私は私が次でこれを行うことができ、すでに、valの上限と下限を持ち、それぞれvalUvalLを言います。方法: "

valUvalLの偏差が元の問題の反復であることは疑いなく正確です - rounded_valを見つけること。 valLvalUを見つけるコードはそれぞれ上限と下限を必要とします。それ以外の場合、不正確なエンドポイントを持つ範囲[valL ... valU]を防ぐにはどうすればよいですか?

関連する問題