C(++)プログラムで最小の負の値を表す(たとえば、負の無限大を使用する)ための標準的および/または移植可能な方法はありますか?
float.hのDBL_MINは、最小の正の数です。
C(++)プログラムで最小の負の値を表す(たとえば、負の無限大を使用する)ための標準的および/または移植可能な方法はありますか?
float.hのDBL_MINは、最小の正の数です。
回答:
-DBL_MAX
ANSI Cでfloat.hの中で定義されています、。
-DBL_MAX
正確に表現可能である必要があるため、FPハードウェアがそれを実行できない場合、実装はそれを回避する必要があります。C99の5.2.4.2.2浮動小数点型<float.h> p2の特性の浮動小数点モデルを参照してください(それ以降、他の場所に移動された可能性があります)。
浮動小数点数(IEEE 754)は対称であるため、最大値(DBL_MAX
またはnumeric_limits<double>::max()
)を表すことができる場合は、マイナス記号を前に付けるだけです。
そして、それはクールな方法です:
double f;
(*((long long*)&f))= ~(1LL<<52);
Cでは、
#include <float.h>
const double lowest_double = -DBL_MAX;
C ++ pre-11では、
#include <limits>
const double lowest_double = -std::numeric_limits<double>::max();
C ++ 11以降では、
#include <limits>
constexpr double lowest_double = std::numeric_limits<double>::lowest();
min
、正の値が最小でlowest
、負の値が最大であることがわかります。はい、それはひどいです。C ++標準ライブラリの素晴らしい世界へようこそ:-P
。
float.h
ます。limits.h
整数のためである
これを試して:
-1 * numeric_limits<double>::max()
参照: numeric_limits
このクラスは、基本的な型ごとに特化されており、そのメンバーは、コンパイルする特定のプラットフォームで型が持つプロパティを定義するさまざまな値を返すか、異なる値に設定されます。
-numeric_limits<double>::max()
ですか?
-1 * ...
、少し明確にするために使用します。
実無限または最小有限値をお探しですか?前者の場合は、
-numeric_limits<double>::infinity()
これは次の場合にのみ機能します
numeric_limits<double>::has_infinity
それ以外の場合は、
numeric_limits<double>::lowest()
これはC ++ 11で導入されました。
lowest()
利用できない場合は、にフォールバックできます
-numeric_limits<double>::max()
これはlowest()
原則とは異なる場合がありますが、通常は実際には異なります。
-numeric_limits<double>::max()
、実際に機能したとしても、理論的には完全に移植可能ではありません。
C ++ 11以降、を使用できます numeric_limits<double>::lowest()
。標準によると、それはあなたが探しているものを正確に返します:
他の有限値yがないような有限値x
y < x
。ここで。
のすべての専門分野にとって意味がありis_bounded != false
ます。
に行く多くの答えがあります-std::numeric_limits<double>::max()
。
幸いなことに、ほとんどの場合にうまく機能します。浮動小数点エンコード方式は、仮数と指数の数値を分解し、それらのほとんど(たとえば、一般的なIEEE-754)は、仮数に属さない別個の符号ビットを使用します。これにより、符号を反転するだけで、最大の正を最小の負に変換できます。
この標準は、浮動小数点標準を課していません。
私の議論は少し理論的であることに同意しますが、一部のエキセントリックなコンパイラメーカーが、2の補数のいくつかのバリエーションで仮数をエンコードした革新的なエンコードスキームを使用するとします。2の補数エンコーディングは対称ではありません。たとえば、符号付き8ビット文字の場合、正の最大値は127ですが、負の最小値は-128です。したがって、いくつかの浮動小数点エンコーディングが同様の非対称動作を示すことを想像できます。
私はそのようなエンコード方式を知りませんが、要点は、標準では符号反転が意図した結果をもたらすことを保証していないということです。したがって、この人気のある回答(申し訳ありませんが!)は、完全にポータブルな標準ソリューションとは見なされません!/ *少なくともそれnumeric_limits<double>::is_iec559
が真実であると主張しなかった場合はそうではありません* /
C(++)プログラムで最小の負の値を表す(たとえば、負の無限大を使用する)ための標準的および/または移植可能な方法はありますか?
Cアプローチ。
多くの実装は+/-無限大をサポートしているため、最も負のdouble
値は-INFINITY
です。
#include <math.h>
double most_negative = -INFINITY;
標準および/またはポータブルな方法はありますか....?
次に、他のケースも考慮する必要があります。
単に-DBL_MAX
。
この場合、OPが好むと思い-DBL_MAX
ます。
DBL_MAX
。よりも大きい非正規値。これは珍しいケースであり、おそらくOPの懸念の範囲外です。double
が目的の範囲/歳差運動を達成するために浮動小数点のペアとしてエンコードされる場合(double-doubleを参照)、最大の法線 double
とおそらくより大きな非法線が存在します。私は、両方の最大のもののうちDBL_MAX
、最大の法線を参照する必要があるかどうかについての議論を見てきました。
幸い、このペアのアプローチには通常-無限大が含まれているため、最も負の値が残り-INFINITY
ます。
移植性を高めるために、コードはルートをたどることができます
// HUGE_VAL is designed to be infinity or DBL_MAX (when infinites are not implemented)
// .. yet is problematic with unsigned infinity.
double most_negative1 = -HUGE_VAL;
// Fairly portable, unless system does not understand "INF"
double most_negative2 = strtod("-INF", (char **) NULL);
// Pragmatic
double most_negative3 = strtod("-1.0e999999999", (char **) NULL);
// Somewhat time-consuming
double most_negative4 = pow(-DBL_MAX, 0xFFFF /* odd value */);
// My suggestion
double most_negative5 = (-DBL_MAX)*DBL_MAX;
float例外を有効にしていない場合(これは私見すべきではありません)、次のように簡単に言うことができます。
double neg_inf = -1/0.0;
これにより、負の無限大が生成されます。フロートが必要な場合は、結果をキャストすることができます
float neg_inf = (float)-1/0.0;
または単精度演算を使用します
float neg_inf = -1.0f/0.0f;
結果は常に同じであり、単精度と倍精度の両方で負の無限大の表現が1つだけあり、期待どおりに相互に変換されます。
-INFINITY
neg_inf
初期化されていることがわかります。コンパイラがinf
値の計算を処理します。また、最大値を計算するためのnull値として使用する場合、通常、最初の反復でより大きな値で上書きされます。つまり、パフォーマンスはほとんど問題になりません。そして、OPは特に「負の無限大を使用する」ことについて-inf
質問し、これに対する唯一の正解です。あなたは正解と有用な答えに反対票を投じました。