cplex.getvalue(x) 返回浮点值,当我将值放入 int 时,它与初始值不同。有没有更好的方法来访问整数变量的值?
现在我只是用一种幼稚的方式,我不知道它是否正确
val = cplex.getObjValue() + 0.1;
for (int i = 0; i < n; i++)
returnX[i] = cplex.getValue(x[i]) + 0.1;
如果您以整数类型(例如 )存储浮点值int
,您将丢失小数点后的任何精度。整数类型只存储整数。如果您将 a 存储float
在 an 中int
,您将丢失小数点后的任何内容。
如果将 0.1 添加到 a float
,您只需得到一个比原始值大大约 0.1 的浮点值。如果将其分配给int
,您将遇到完全相同的问题。你只是要截断一个不同的值。
如果您需要 afloat
保持其精度,只需将其存储在 a 中float
(或 adouble
以获得更高的精度)。
如果您正在进行转换int -> float -> int
,例如原始int
值是一个值,而最终得到的值是不同int
的,那么这就是发生的情况。到 a 的转换float
是不对称的。int
tofloat
转换将转换为最接近的可表示值float
,而float
toint
转换将截断。
浮点类型的纯右值可以转换为整数类型的纯右值。转换截断;也就是说,小数部分被丢弃。[...]
整数类型或无作用域枚举类型的纯右值可以转换为浮点类型的纯右值。如果可能,结果是准确的。如果要转换的值在可以表示的值范围内但不能准确表示,则它是实现定义的下一个较低或较高可表示值的选择。[...]
解决方案是不转换为中间float
. 如果你想要一个int
,保持它一个int
。如果由于某种原因你的函数返回 a 是有意义的,float
尽管它计算的东西是 aint
那么你必须接受后果。
首先,将其转换为 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() 函数。