2013-02-26 18 views
11

実際に私はC++で範囲式に取り組んでいます。私はその後、別のdouble値よりも小さいdouble値を出力するには?

x<1 

のような任意の式を持っているのであれば、私がしたいことはある私の

double getMax(...); 

数直線上だけで1.000(倍精度)の前にある二重の値を返す必要があります。

私はこの

double getMax(double& a) 
{ 
    return (a-numeric_limits<double>::min()); 
} 

をやってみました。しかし、私はまだリターンで文として同じ値を取得しています。

私はC++がcout文の中で最も近いdoubleに変換していると思います。

int main() 
{ 
    double a = 32; 
    cout<<scientific<<getMax(a)<<endl; 
    return 0; 
} 

出力:

3.200000e+001 
+0

「getMax」は開いている間隔には意味がなく、[getSup'](http://en.wikipedia.org/wiki/Supremum)は1を正確に返す必要があります。 –

答えて

10

まず、実際に十分多くの桁を印刷して、表現可能なすべての値がdoubleであることを確認する必要があります。次のようにあなたは(あなたの本のために#include <iomanip>を確認してください)これを行うことができます。第二に

std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl; 

numeric_limits<>::minはこのために適切ではありません。開始値が1.0の場合、numeric_limits<double>::epsilonを使用することができます。これは1.0と表現可能な最小の差です。

ただし、コード例では、開始値は32です。イプシロンは必ずしもそのためには機能しません。この場合の右イプシロンの計算は困難です。

#include <iostream> 
#include <limits> 
#include <iomanip> 
#include <cmath> 

double getMax(double a) 
{ 
    return std::nextafter(a,std::numeric_limits<double>::lowest()); 
} 

int main() 
{ 
    double a = 32; 
    std::cout << std::scientific 
       << std::setprecision(std::numeric_limits<double>::max_digits10) 
       << getMax(a) 
       << std::endl; 
    return 0; 
} 

私もliveworkspaceの上に置かれている:あなたがC++ 11 を使用できるかどう

ただし、(*)は、cmathヘッダ内の関数を使用すると、std::nextafterが必要なものないものがあります。説明する

double nextafter(double from, double to); 

はの方向からの次の表現可能な値を返します。だから私はstd::numeric_limits<double>::lowest()を指定して、次の表現可能な値を確実に受け取って、引数を以下にしました。

(*)下記のTony Dのコメントを参照してください。 nextafter()にC++ 11を使用せずにアクセスできます。

+1

コメント行は 'a - a * ... :: epsilon()'であってはなりませんか? –

+0

ああ、まあ、それはゼロに向かって丸くなります。そして、 '2 * a * ... ::ε()'は、丸められれば正しい値になりますが、そうでなければ2倍大きくなります。大したことだ。 –

+0

@JanHudec '10'はコードを提出する前にテストしたものです。私はそれを削除しました。 'a 'を乗算するのが正しいかどうかはわかりません。正しい要素を選択することは私の知るところではありません。私の主なポイントはC++ 11で 'nextafter'を使うことでした。イプシロンの正確な計算のために、誰かが答えを作るかもしれません。 – jogojapan

0

私はあなたが正しい考えを持っていると思います。 Setting the precision of a double without using stream (ios_base::precision)を調べてください。質問にはそれほど多くはありませんが、彼らはprecisionを使用しています。

「近くにはあるが、あまりない」と表示される方法には、差の閾値(通常はイプシロンと呼ばれます)を設定することが含まれます。その場合、getMax関数は使用しませんが、より小さい使用法ではイプシロンを使用します。 (。あなたがイプシロン値と演算子のオーバーロードを持つクラスを行うことができ、私は疫病のように演算子オーバーロードを避ける傾向にある。)

基本的には、必要があると思います:

bool lessThanEpsilon(double number, double lessThan, double epsilon) 
{ 
    return (lessThan - number >= epsilon); 
} 

もちろん他の品種がありますが、 。等しいとチェックしますif Math.abs(number - equals) < epsilon

関連する問題