-4

cplex.getvalue(x) は float 値を返し、値を int に入れると、最初の値とは異なります。整数変数の値にアクセスするより良い方法はありますか?

今、私は単純な方法を使用しているだけで、それが正しいかどうかはわかりません

val = cplex.getObjValue() + 0.1;

 for (int i = 0; i < n; i++)
   returnX[i] = cplex.getValue(x[i]) + 0.1;
4

3 に答える 3

3

浮動小数点値を整数型 ( などint) に格納すると、小数点以下の精度が失われます。整数型は単に整数のみを格納します。を に格納するfloatint、小数点以下はすべて失われます。

に 0.1 を追加するとfloat、元の値よりも約 0.1 大きい浮動小数点値が得られます。それをに割り当てると、intまったく同じ問題が発生します。別の値を切り捨てるだけです。

の精度を保持する必要がある場合は、単純に(またはさらに高い精度の場合は)floatに格納します。floatdouble

int -> float -> intintの値が 1 つの値で、最後に取得した値が異なるような変換を行っている場合は、intまさにそれが起こります。a への変換floatは対称的ではありません。inttofloat変換は最も近い表現可能なfloat値に変換されますが、floattoint変換は切り捨てられます。

浮動小数点型の prvalue は、整数型の prvalue に変換できます。変換は切り捨てられます。つまり、小数部分は破棄されます。[...]

整数型またはスコープなし列挙型の prvalue は、浮動小数点型の prvalue に変換できます。可能であれば、結果は正確です。変換される値が表現できる値の範囲内にあるが、その値を正確に表現できない場合は、表現可能な次の低い値または高い値の実装定義の選択になります。[...]

これに対する解決策は、中間体に変換しないことfloatです。が必要な場合は、そのintままにしておきますintfloatなんらかの理由で、関数が計算するものが であったにもかかわらず、関数が を返すことが理にかなっているint場合は、結果を受け入れる必要があります。

于 2013-03-06T18:07:50.383 に答える
1

まず、int にキャストすると精度値が失われます。あなたができることは、値を四捨五入することです。

例:

float fVal = 10.89;

int nVal = (fVal > 0.0) ? (fVal + 0.5) : (fVal - 0.5);
于 2013-03-06T18:10:35.280 に答える
0

C++ は (最も近いものに丸めるのではなく) ゼロに丸め、浮動小数点数は正確ではない可能性のあるおおよその値 (0.9999997f など) を格納するため、遭遇した結果が得られます

+0.001 を追加しても問題ありません。最も近いものに丸めたい場合は、0.5f を追加してから、C++ に心ゆくまで切り捨ててもらいます。

float closerToFive = 5.454f;
float closerToSix = 5.545f;

int five = static_cast<int>(closerToFive + 0.5f);
int six = static_cast<int>(closerToSix + 0.5f);

「素朴なやり方」かもしれませんが、うまくいきます。頻繁に行う場合は、func でラップします。

constexpr int ftoi(float value)
{
    return static_cast<int>(value + (value > 0.0f? 0.5f : -0.5f));
}


ftoi(5.454f) -> 5
ftoi(5.545f) -> 6
ftoi(-5.454f) -> -5
ftoi(-5.545f) -> -6

http://ideone.com/gDT4GP

編集: CasperGhost の回答が示すように、負のフロートを考慮するのを忘れていました。ftoi() 関数を修正しました。

于 2013-03-06T18:15:28.723 に答える