-4

cplex.getvalue(x) return float value, and when I put the value in int, it's different from the initial one. Is there a better way to accessing the integer variable's value?

Now I just use a naive way and I don't know whether it's right or not

val = cplex.getObjValue() + 0.1;

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

3 Answers3

3

If you store a floating point value in an integral type (such as int), you are going to lose any precision after the decimal point. Integral types simply only store integers. If you store a float in an int, you will lose anything after the decimal point.

If you add 0.1 to a float, you simply get a floating point value approximately 0.1 greater than the original value. If you assign that to an int, you'll have exactly the same problem. You're just going to truncate a different value.

If you need a float to retain its precision, simply store it in a float (or a double for even higher precision).

If perhaps you are doing a conversion like int -> float -> int where the original int is of one value and the value you get at the end is a different int, well that's just what happens. The conversion to a float is not symmetric. The int to float conversion will convert to the nearest representable float value, whereas the float to int conversion will truncate.

A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. [...]

A prvalue of an integer type or of an unscoped enumeration type can be converted to a prvalue of a floating point type. The result is exact if possible. If the value being converted is in the range of values that can be represented but the value cannot be represented exactly, it is an implementation-defined choice of either the next lower or higher representable value. [...]

The solution to this is to not convert to an intermediate float. If you want an int, keep it an int. If for some reason it makes sense for your function to return a float despite the fact that the thing it calculate was an int then you have to accept the consequences.

Community
  • 1
  • 1
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • As long as an `int` is within the number of bits that a `float` has (typically 23 bits, so about 8million definitely works, up to 16.2 million will probably work), nothing is lost (or gained) from storing it in `float`. But if some math is done to the float (adding, subtracting, multiplying or dividing) then the value may lose or gain bits, and thus no longer translate back to the original value, even if all the math should result in exactly the smae number. – Mats Petersson Mar 06 '13 at 18:49
  • Thanks for the detailed explanation of int and float, it's really good to know how the code actually works. Do you use cplex? Actually I think it should has the function to return the integer value directly. – snowying Mar 06 '13 at 19:09
1

Firstly, you will lose precision value when casting it to int. You can do is round off the value.

Example:

float fVal = 10.89;

int nVal = (fVal > 0.0) ? (fVal + 0.5) : (fVal - 0.5);
CasperGhost
  • 117
  • 7
0

Because C++ rounds towards zero (instead of rounding to the nearest), and because floats store the aproximate value which may not be exactly accurate (e.g. 0.9999997f), then you get the results you are encountering.

Adding +0.001 is fine. If you're really wanting to round to the nearest, add 0.5f, and then let C++ round down to its heart's content.

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

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

Maybe it's a "naive way", but it works well. Wrap it in a func if you do it alot:

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

Edit: Forgot to take into account negative floats, as CasperGhost's answer indicates. Fixed the ftoi() func.

Jamin Grey
  • 10,151
  • 6
  • 39
  • 52