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;
浮動小数点値を整数型 ( などint
) に格納すると、小数点以下の精度が失われます。整数型は単に整数のみを格納します。を に格納するfloat
とint
、小数点以下はすべて失われます。
に 0.1 を追加するとfloat
、元の値よりも約 0.1 大きい浮動小数点値が得られます。それをに割り当てると、int
まったく同じ問題が発生します。別の値を切り捨てるだけです。
の精度を保持する必要がある場合は、単純に(またはさらに高い精度の場合は)float
に格納します。float
double
int -> float -> int
元int
の値が 1 つの値で、最後に取得した値が異なるような変換を行っている場合は、int
まさにそれが起こります。a への変換float
は対称的ではありません。int
tofloat
変換は最も近い表現可能なfloat
値に変換されますが、float
toint
変換は切り捨てられます。
浮動小数点型の prvalue は、整数型の prvalue に変換できます。変換は切り捨てられます。つまり、小数部分は破棄されます。[...]
整数型またはスコープなし列挙型の prvalue は、浮動小数点型の prvalue に変換できます。可能であれば、結果は正確です。変換される値が表現できる値の範囲内にあるが、その値を正確に表現できない場合は、表現可能な次の低い値または高い値の実装定義の選択になります。[...]
これに対する解決策は、中間体に変換しないことfloat
です。が必要な場合は、そのint
ままにしておきますint
。float
なんらかの理由で、関数が計算するものが であったにもかかわらず、関数が を返すことが理にかなっているint
場合は、結果を受け入れる必要があります。
まず、int にキャストすると精度値が失われます。あなたができることは、値を四捨五入することです。
例:
float fVal = 10.89;
int nVal = (fVal > 0.0) ? (fVal + 0.5) : (fVal - 0.5);
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
編集: CasperGhost の回答が示すように、負のフロートを考慮するのを忘れていました。ftoi() 関数を修正しました。