2017-10-30 10 views
-2

This私がしたコードです:これらのステップラウンドは同等ですか?

#include <iostream> 
#include <limits> 
#include <math.h> 
#include <stdio.h> 

typedef std::numeric_limits<double> dbl; 

double StepValue(double value) { 
    return floor(0.5 + value/0.1) * 0.1; 
} 

void PrintValue(int maxlen, const char *fmt, ...) 
{ 
    char buffer[20]; 
    va_list arglist; 
    va_start(arglist, fmt); 
    vsnprintf(buffer, maxlen, fmt, arglist); 
    va_end(arglist); 

    std::cout << "p: " << buffer << std::endl; 
} 

int main() 
{ 
    std::cout.precision(dbl::max_digits10); 
    std::cout << std::fixed; 

    double inputValue = 13.55121341223423457; 
    std::cout << "v: " << inputValue << std::endl; 

    double steppedValue = StepValue(inputValue); 
    std::cout << "f: " << steppedValue << std::endl; 

    PrintValue(20, "%.1f", inputValue); 
} 

基本的に、私はinputValueを取ると私はそれができ最寄りのダブルを使用して、(カンマの後に1桁である)私は必要最寄りの強化値に丸めますそれを表現する(私がsteppedValueに割り当てるもの)。

、値が13.6されるように、例えば、inputValue = 13.55121341223423457を取り、0.1のステップを使用して(実際13.60000000000000142による浮動小数点演算にある;しかし、それは点ではない点は、それが概念的に0.6を返すことです)。

その後、私は同じinputValueをとり、0.1のステップを再度考慮してvsnprintf関数を使用して印刷します。どちらが正しく印刷されますか13.6

私の質問は:私のステップ関数またはvsnprintfの使用の間に異なるステップ値に丸められたANY inputValueが存在する可能性がありますか?すなわち、2つの結果が私のステップ関数から得られ、vsnprintfは、異なるステップで計算/印刷値などの矛盾している可能性がありますか?

+1

あなたの投稿をコードの*テキスト*で編集してください。ファイアウォールはコードページへのリンクをブロックします。画面のスナップショットはしないでください。 –

+0

@ThomasMatthews:done;)ありがとう – markzzz

答えて

1

これらは同等ではありません。 10で掛け合わせるのではなく、0.1で割っているので(正確に表現することはできません)、丸めが異なる方向に行く中点に非常に近い数があります。これは、コンパイラと実行環境によって異なります。 Visual Studioの2015年では、32ビットプログラムとしてコンパイルし、

double inputValue = std::nextafter(0.05, 0.0); 

を使用すると、あなたの丸めに10を乗じ

f: 0.10000000000000001 
p: 0.0 

の値は、問題を解決することができますが、それはvsnprintfハンドルは、丸め方法によって異なります。

StepValueからreturn std::round(value * 10.0)/10.0;に変更すると、私が指定した値の問題が解決します。

+0

Uhm interessant!どうすれば2つの操作を "同期"できますか?私は 'vsnprintf'がその丸めをどのように処理するのか分かりません。もちろん、それは私の "フロア+ 0.5"アッチをしません。 – markzzz

+0

「ラウンド」も使用できますが、どちらがタイブレークですか?それは推測のようです... – markzzz

+0

あなたのCライブラリの 'printf'ファミリの実装を正確に見ることを掘り下げたいのでない限り、' round'を使うのはおそらく最高の推測です。この問題は、丸めエッジ値に非常に近い値でのみ発生します。 – 1201ProgramAlarm

関連する問題