通过c ++访问精确的积分变量的值

时间:2013-03-06 18:01:51

标签: c++ solution cplex

cplex.getvalue(x)返回浮点值,当我将值放入int时,它与初始值不同。有没有更好的方法来访问整数变量的值?

现在我只是用一种天真的方式而且我不知道它是否正确

val = cplex.getObjValue() + 0.1;

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

3 个答案:

答案 0 :(得分:3)

如果将浮点值存储在整数类型(例如int)中,则小数点后将失去任何精度。积分类型只存储整数。如果您在float中存储int,则小数点后将丢失任何内容。

如果向float添加0.1,则只需获得比原始值大约0.1的浮点值。如果您将其分配给int,则会遇到完全相同的问题。你只是要截断一个不同的值。

如果您需要float来保持其精确度,只需将其存储在float(或double中,以获得更高的精度)。

如果您正在进行int -> float -> int之类的转换,其中原始int具有一个值,而您在最后得到的值是不同的int,那就是发生了什么。转换为float不对称。 intfloat转换将转换为最接近的可表示float值,而floatint转换将截断。

  

浮点类型的prvalue可以转换为整数类型的prvalue。转换截断;也就是说,丢弃小数部分。 [...]

     

整数类型或无范围枚举类型的prvalue可以转换为浮点类型的prvalue。如果可能,结果是准确的。如果要转换的值在可以表示的值范围内,但该值无法准确表示,则它是实现定义的下一个较低或较高可表示值的选择。 [...]

解决方法是不转换为中间float。如果您需要int,请将其保留为int。如果出于某种原因,你的函数返回float是有意义的,尽管它计算的东西是int,那么你必须接受后果。

答案 1 :(得分:1)

首先,将它转换为int时会丢失精度值。你可以做的就是完善价值。

示例:

float fVal = 10.89;

int nVal = (fVal > 0.0) ? (fVal + 0.5) : (fVal - 0.5);

答案 2 :(得分:0)

因为C ++向零舍入(而不是舍入到最近),并且因为浮点数存储 aproximate 值,这可能不准确(例如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);

也许这是一种“天真的方式”,但效果很好。如果你这么做的话,把它包裹在一个函数中:

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()函数。