Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct type in c\c++ to store a COM's VT_DECIMAL?

Tags:

c++

decimal

com

ado

I'm trying to write a wrapper to ADO.

A DECIMAL is one type a COM VARIANT can be, when the VARIANT type is VT_DECIMAL.

I'm trying to put it in c native data type, and keep the variable value. it seem that the correct type is long double, but I get "no suitable conversion error".

For example:

_variant_t v;
...

if(v.vt == VT_DECIMAL)
{
  double d = (double)v; //this works but I'm afraid can be loss of data...
  long double ld1 = (long double)v; //error: more then one conversion from variant to long double applied.
  long double ld2 = (long double)v.decVal; //error: no suitable conversion function from decimal to long double exist.  
}

So my questions are:

  1. is it totally safe to use double to store all possible decimal values?

  2. if not, how can I convert the decimal to a long double?

  3. How to convert a decimal to string? (using the << operator, sprintf is also good for me)

like image 221
SHR Avatar asked Dec 18 '22 22:12

SHR


1 Answers

The internal representation for DECIMAL is not a double precision floating point value, it is integer instead with sign/scale options. If you are going to initialize DECIMAL parts, you should initialize these fields - 96-bit integer value, scale, sign, then you get valid decimal VARIANT value.

DECIMAL on MSDN:

  • scale - The number of decimal places for the number. Valid values are from 0 to 28. So 12.345 is represented as 12345 with a scale of 3.
  • sign - Indicates the sign; 0 for positive numbers or DECIMAL_NEG for negative numbers. So -1 is represented as 1 with the DECIMAL_NEG bit set.
  • Hi32 - The high 32 bits of the number.
  • Lo64 - The low 64 bits of the number. This is an _int64.

Your questions:

is it totally safe to use double to store all possible decimal values?

You cannot initialize as double directly (e.g. VT_R8), but you can initialize as double variant and use variant conversion API to convert to VT_DECIMAL. A small rounding can be applied to value.

if not, how can I convert the decimal to a long double?

How to convert a decimal to string? (using the << operator, sprintf is also good for me)

VariantChangeType can convert decimal variant to variant of another type, including integer, double, string - you provide the type to convert to. Vice versa, you can also convert something different to decimal.

like image 173
Roman R. Avatar answered Dec 24 '22 01:12

Roman R.