20

タイトルは一目瞭然で、入力には2倍の値が与えられ、可能な限り最小限の量を加算/減算したい.

4

4 に答える 4

28

を使用できますnextafter。これは、コンパイラが C99 の数学関数 (つまり、C++11 以降) を実装している場合に使用できます。この関数 (およびそのさまざまなオーバーロード) は、次のように記述できます。

double nextafter(double value, double target);

value 可能な限り最小量だけの方向に 移動targetします (通常は float のビット表現を微調整することによって)。valueがすでに にある場合target、これは何もしません。

targetがこれよりも大きい場合は、可能な限り最小の量だけvalue増加します。がこれよりも小さいvalue場合は、可能な限り最小の量だけ減少します。targetvaluevalue

DBL_MAX一般的な使用法は、またはのいずれかをターゲットとして渡しINFINITY、最小量を増やします (または、それらを否定して最小量を減らします)。

とのどちらを選択するかは、境界DBL_MAXINFINITY何をしたいかによって異なりますnextafter(DBL_MAX, DBL_MAX) == DBL_MAXが、nextafter(DBL_MAX, INFINITY) == INFINITY.

そして、はい、それは悪い名前です。nextafterおよびnexttowardも参照してください: なぜこの特定のインターフェイス? .


#include <cfloat> // DBL_MAX
#include <cmath> // std::nextafter

double x = 0.1;

// Next representable number **after** x in the direction of DBL_MAX.
// (i.e., this is larger than x, and there is no double between it and x)
double xPlusSmallest = std::nextafter(x, DBL_MAX); 

// Next representable number **before** x in the direction of -DBL_MAX.
// (i.e., this is smaller than x, and there is no double between it and x)
double xMinusSmallest = std::nextafter(x, -DBL_MAX); 

コンパイラがそれをサポートしていなくても、おそらく組み込み関数があります。_nextafter(たとえば、MSVC には2005 年からあります。GCC はおそらくそれを標準として実装しています。)

コンパイラがサポートしていなくても Boost を利用できる場合は、次のようにすることができます。

#include <boost/math/special_functions/next.hpp>
#include <cfloat> 

double x = 0.1;

double xPlusSmallest = boost::math::nextafter(x, DBL_MAX); 
double xMinusSmallest = boost::math::nextafter(x, -DBL_MAX); 

これらのいずれもうまくいかない場合は、Boost ヘッダーを開いてコピーするだけです。

于 2012-04-15T07:13:23.433 に答える
7

これは、実際には合法ではなく、プラットフォームが IEEE754 浮動小数点数を使用している場合にのみ機能する非常に汚いトリックです: 浮動小数点数のバイナリ表現は、浮動小数点値と同じ方法で順序付けられるため、バイナリ表現をインクリメントできます:

double x = 1.25;

uint64_t * const p = reinterpret_cast<uint64_t*>(&x);

++*p;   // undefined behaviour! but it gets the next value

// now x has the next value

通常のバイナリ コピー体操を行って適切な値を取得することにより、完全に合法的に同じ効果を得ることができuint64_tます。ゼロ、無限大、NaN も適切にチェックしてください。

于 2012-04-15T08:51:18.580 に答える
-4

どうですか:

x += fabs(x) * std::numeric_limits<double>::epsilon();
于 2012-04-15T09:04:28.630 に答える
-5
#define FLT_MIN         1.175494351e-38F        /* min positive value */
#define FLT_MAX         3.402823466e+38F        /* max value */
#define DBL_MIN         2.2250738585072014e-308 /* min positive value */
#define DBL_MAX         1.7976931348623158e+308 /* max value */

http://xona.com/2006/07/26.html

于 2012-04-15T06:49:09.170 に答える