-1

I have variant of VT_R4/float type with value "2.550000" when converting it to double using VariantChangeType() to VT_R8/double type value becomes "2.54999999998".

::VariantChangeType(&var, &var, 0, VT_BSTR);
::VariantChangeType(&var, &var, 0, VT_R8);
double dOutputValue = var.dblVal; 

this double when is when rounded of using

output.Format(_T("%3.1f"), dOutputValue);

gives value 2.5, instead of 2.6 as expected.

Please suggest.

Peeyush
  • 31
  • 6

1 Answers1

1

I have variant of VT_R4/float type with value "2.550000".

No you don't. That value is not exactly representable in a binary floating point type. The closest single precision value to 2.55 is:

2.5499999523162841796875

If you wish to represent 2.55 exactly you will need to use a decimal data type rather than a binary data type.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Or a rational data type. Or something else. There are a lot of possible solutions, but as you say, `float` and `double` aren't among them. (You might also point out that this comment is "typical": the standard does allow a decimal floating point representation, although the last machine I saw which used such internally was well before the days of C++, or even C.) – James Kanze Dec 11 '14 at 12:02
  • @James The standard in play here is the COM variant data type, VT_R4. That's IEEE754 binary single precision. A rational would do the trick too. – David Heffernan Dec 11 '14 at 12:08
  • I want to get 2.6 as output, currently it is giving 2.5 instead. the same code works well for all other values, execpt mid point value rounding of. – Peeyush Dec 11 '14 at 12:24
  • Please try and understand my answer and realise that your variant does not hold the value 2.55 in a VT_R4 because there is simply no VT_R4 with that exact value. – David Heffernan Dec 11 '14 at 13:01