oleaut32: Get rid of the DECIMAL access macros.
This commit is contained in:
parent
641623ffe8
commit
36963b6d27
3 changed files with 188 additions and 218 deletions
|
@ -30,9 +30,6 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
@ -428,13 +425,13 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
|
|||
{
|
||||
case VT_EMPTY:
|
||||
case VT_BOOL:
|
||||
DEC_SIGNSCALE(&V_DECIMAL(pd)) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_HI32(&V_DECIMAL(pd)) = 0;
|
||||
DEC_MID32(&V_DECIMAL(pd)) = 0;
|
||||
V_DECIMAL(pd).sign = DECIMAL_POS;
|
||||
V_DECIMAL(pd).scale = 0;
|
||||
V_DECIMAL(pd).Hi32 = 0;
|
||||
/* VarDecFromBool() coerces to -1/0, ChangeTypeEx() coerces to 1/0.
|
||||
* VT_NULL and VT_EMPTY always give a 0 value.
|
||||
*/
|
||||
DEC_LO32(&V_DECIMAL(pd)) = vtFrom == VT_BOOL && V_BOOL(ps) ? 1 : 0;
|
||||
V_DECIMAL(pd).Lo64 = vtFrom == VT_BOOL && V_BOOL(ps) ? 1 : 0;
|
||||
return S_OK;
|
||||
case VT_I1: return VarDecFromI1(V_I1(ps), &V_DECIMAL(pd));
|
||||
case VT_I2: return VarDecFromI2(V_I2(ps), &V_DECIMAL(pd));
|
||||
|
@ -903,7 +900,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, const VARIANTARG* pvargSrc)
|
|||
}
|
||||
else if (V_VT(pSrc) == (VT_DECIMAL|VT_BYREF))
|
||||
{
|
||||
memcpy(&DEC_SCALE(&V_DECIMAL(pvargDest)), &DEC_SCALE(V_DECIMALREF(pSrc)),
|
||||
memcpy(&V_DECIMAL(pvargDest).scale, &V_DECIMALREF(pSrc)->scale,
|
||||
sizeof(DECIMAL) - sizeof(USHORT));
|
||||
}
|
||||
else
|
||||
|
@ -2159,9 +2156,10 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
|
|||
else if ((dwVtBits & VTBIT_DECIMAL) == VTBIT_DECIMAL)
|
||||
{
|
||||
V_VT(pVarDst) = VT_DECIMAL;
|
||||
DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
|
||||
DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
|
||||
V_DECIMAL(pVarDst).sign = DECIMAL_POS;
|
||||
V_DECIMAL(pVarDst).scale = 0;
|
||||
V_DECIMAL(pVarDst).Hi32 = 0;
|
||||
V_DECIMAL(pVarDst).Lo64 = ul64;
|
||||
return S_OK;
|
||||
}
|
||||
else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
|
||||
|
@ -2344,9 +2342,10 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
|
|||
{
|
||||
/* Decimal is only output choice left - fast path */
|
||||
V_VT(pVarDst) = VT_DECIMAL;
|
||||
DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_NEG,0);
|
||||
DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
|
||||
DEC_LO64(&V_DECIMAL(pVarDst)) = -ul64;
|
||||
V_DECIMAL(pVarDst).sign = DECIMAL_NEG;
|
||||
V_DECIMAL(pVarDst).scale = 0;
|
||||
V_DECIMAL(pVarDst).Hi32 = 0;
|
||||
V_DECIMAL(pVarDst).Lo64 = -ul64;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
@ -2406,9 +2405,10 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
|
|||
{
|
||||
/* Decimal is only output choice left - fast path */
|
||||
V_VT(pVarDst) = VT_DECIMAL;
|
||||
DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
|
||||
DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
|
||||
V_DECIMAL(pVarDst).sign = DECIMAL_POS;
|
||||
V_DECIMAL(pVarDst).scale = 0;
|
||||
V_DECIMAL(pVarDst).Hi32 = 0;
|
||||
V_DECIMAL(pVarDst).Lo64 = ul64;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
@ -2514,30 +2514,30 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
|
|||
DECIMAL* pDec = &V_DECIMAL(pVarDst);
|
||||
|
||||
DECIMAL_SETZERO(*pDec);
|
||||
DEC_LO32(pDec) = 0;
|
||||
pDec->Lo32 = 0;
|
||||
|
||||
if (pNumprs->dwOutFlags & NUMPRS_NEG)
|
||||
DEC_SIGN(pDec) = DECIMAL_NEG;
|
||||
pDec->sign = DECIMAL_NEG;
|
||||
else
|
||||
DEC_SIGN(pDec) = DECIMAL_POS;
|
||||
pDec->sign = DECIMAL_POS;
|
||||
|
||||
/* Factor the significant digits */
|
||||
for (i = 0; i < pNumprs->cDig; i++)
|
||||
{
|
||||
tmp = (ULONG64)DEC_LO32(pDec) * 10 + rgbDig[i];
|
||||
tmp = (ULONG64)pDec->Lo32 * 10 + rgbDig[i];
|
||||
carry = (ULONG)(tmp >> 32);
|
||||
DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
|
||||
tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
|
||||
pDec->Lo32 = (ULONG)tmp;
|
||||
tmp = (ULONG64)pDec->Mid32 * 10 + carry;
|
||||
carry = (ULONG)(tmp >> 32);
|
||||
DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
|
||||
tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
|
||||
DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
|
||||
pDec->Mid32 = (ULONG)tmp;
|
||||
tmp = (ULONG64)pDec->Hi32 * 10 + carry;
|
||||
pDec->Hi32 = (ULONG)tmp;
|
||||
|
||||
if (tmp >> 32 & UI4_MAX)
|
||||
if (tmp >> 32)
|
||||
{
|
||||
VarNumFromParseNum_DecOverflow:
|
||||
TRACE("Overflow\n");
|
||||
DEC_LO32(pDec) = DEC_MID32(pDec) = DEC_HI32(pDec) = UI4_MAX;
|
||||
pDec->Lo32 = pDec->Mid32 = pDec->Hi32 = UI4_MAX;
|
||||
return DISP_E_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
@ -2545,20 +2545,20 @@ VarNumFromParseNum_DecOverflow:
|
|||
/* Account for the scale of the number */
|
||||
while (multiplier10 > 0)
|
||||
{
|
||||
tmp = (ULONG64)DEC_LO32(pDec) * 10;
|
||||
tmp = (ULONG64)pDec->Lo32 * 10;
|
||||
carry = (ULONG)(tmp >> 32);
|
||||
DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
|
||||
tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
|
||||
pDec->Lo32 = (ULONG)tmp;
|
||||
tmp = (ULONG64)pDec->Mid32 * 10 + carry;
|
||||
carry = (ULONG)(tmp >> 32);
|
||||
DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
|
||||
tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
|
||||
DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
|
||||
pDec->Mid32 = (ULONG)tmp;
|
||||
tmp = (ULONG64)pDec->Hi32 * 10 + carry;
|
||||
pDec->Hi32 = (ULONG)tmp;
|
||||
|
||||
if (tmp >> 32 & UI4_MAX)
|
||||
if (tmp >> 32)
|
||||
goto VarNumFromParseNum_DecOverflow;
|
||||
multiplier10--;
|
||||
}
|
||||
DEC_SCALE(pDec) = divisor10;
|
||||
pDec->scale = divisor10;
|
||||
|
||||
V_VT(pVarDst) = VT_DECIMAL;
|
||||
return S_OK;
|
||||
|
@ -3077,8 +3077,7 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
resvt = VT_NULL;
|
||||
break;
|
||||
case VT_DECIMAL:
|
||||
if (DEC_HI32(&V_DECIMAL(right)) ||
|
||||
DEC_LO64(&V_DECIMAL(right)))
|
||||
if (V_DECIMAL(right).Hi32 || V_DECIMAL(right).Lo64)
|
||||
resvt = VT_NULL;
|
||||
break;
|
||||
case VT_BSTR:
|
||||
|
@ -4113,7 +4112,7 @@ HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
|
|||
hRet = S_OK;
|
||||
goto VarOr_Exit;
|
||||
case VT_DECIMAL:
|
||||
if (DEC_HI32(&V_DECIMAL(pVarLeft)) || DEC_LO64(&V_DECIMAL(pVarLeft)))
|
||||
if (V_DECIMAL(pVarLeft).Hi32 || V_DECIMAL(pVarLeft).Lo64)
|
||||
goto VarOr_AsEmpty;
|
||||
hRet = S_OK;
|
||||
goto VarOr_Exit;
|
||||
|
@ -4386,7 +4385,7 @@ HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut)
|
|||
hRet = VarCyAbs(V_CY(pVarIn), & V_CY(pVarOut));
|
||||
break;
|
||||
case VT_DECIMAL:
|
||||
DEC_SIGN(&V_DECIMAL(pVarOut)) &= ~DECIMAL_NEG;
|
||||
V_DECIMAL(pVarOut).sign &= ~DECIMAL_NEG;
|
||||
break;
|
||||
case VT_UI1:
|
||||
case VT_UI2:
|
||||
|
@ -5872,7 +5871,7 @@ HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
case VT_DATE: if (!V_DATE(right)) resvt = VT_NULL; break;
|
||||
case VT_CY: if (!V_CY(right).int64) resvt = VT_NULL; break;
|
||||
case VT_DECIMAL:
|
||||
if (!(DEC_HI32(&V_DECIMAL(right)) || DEC_LO64(&V_DECIMAL(right))))
|
||||
if (!V_DECIMAL(right).Hi32 || V_DECIMAL(right).Lo64)
|
||||
resvt = VT_NULL;
|
||||
break;
|
||||
case VT_BSTR:
|
||||
|
@ -5922,7 +5921,7 @@ HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
case VT_R8: if (V_R8(left) == -1.0) resvt = VT_NULL; break;
|
||||
case VT_CY: if (V_CY(left).int64 == -1) resvt = VT_NULL; break;
|
||||
case VT_DECIMAL:
|
||||
if (DEC_HI32(&V_DECIMAL(left)) == 0xffffffff)
|
||||
if (V_DECIMAL(left).Hi32 == 0xffffffff)
|
||||
resvt = VT_NULL;
|
||||
break;
|
||||
case VT_BSTR:
|
||||
|
|
|
@ -74,26 +74,6 @@
|
|||
/* Value of sign for a positive decimal number */
|
||||
#define DECIMAL_POS 0
|
||||
|
||||
/* Native headers don't change the union ordering for DECIMAL sign/scale (duh).
|
||||
* This means that the signscale member is only useful for setting both members to 0.
|
||||
* SIGNSCALE creates endian-correct values so that we can properly set both at once
|
||||
* to values other than 0.
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define SIGNSCALE(sign,scale) (((scale) << 8) | sign)
|
||||
#else
|
||||
#define SIGNSCALE(sign,scale) (((sign) << 8) | scale)
|
||||
#endif
|
||||
|
||||
/* Macros for getting at a DECIMAL's parts */
|
||||
#define DEC_SIGN(d) ((d)->u.s.sign)
|
||||
#define DEC_SCALE(d) ((d)->u.s.scale)
|
||||
#define DEC_SIGNSCALE(d) ((d)->u.signscale)
|
||||
#define DEC_HI32(d) ((d)->Hi32)
|
||||
#define DEC_MID32(d) ((d)->u1.s1.Mid32)
|
||||
#define DEC_LO32(d) ((d)->u1.s1.Lo32)
|
||||
#define DEC_LO64(d) ((d)->u1.Lo64)
|
||||
|
||||
#define DEC_MAX_SCALE 28 /* Maximum scale for a decimal */
|
||||
|
||||
/* Internal flags for low level conversion functions */
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
|
@ -2176,9 +2173,9 @@ HRESULT WINAPI VarI8FromCy(CY cyIn, LONG64* pi64Out)
|
|||
(*pi64Out)--; /* Mimic Win32 bug */
|
||||
else
|
||||
{
|
||||
cyIn.int64 -= *pi64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */
|
||||
cyIn.int64 -= *pi64Out * CY_MULTIPLIER; /* cyIn.Lo now holds fractional remainder */
|
||||
|
||||
if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pi64Out & 0x1)))
|
||||
if (cyIn.Lo > CY_HALF || (cyIn.Lo == CY_HALF && (*pi64Out & 0x1)))
|
||||
(*pi64Out)++;
|
||||
}
|
||||
return S_OK;
|
||||
|
@ -2331,19 +2328,19 @@ HRESULT WINAPI VarI8FromUI4(ULONG ulIn, LONG64* pi64Out)
|
|||
*/
|
||||
HRESULT WINAPI VarI8FromDec(const DECIMAL *pdecIn, LONG64* pi64Out)
|
||||
{
|
||||
if (!DEC_SCALE(pdecIn))
|
||||
if (!pdecIn->scale)
|
||||
{
|
||||
/* This decimal is just a 96 bit integer */
|
||||
if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
|
||||
if (pdecIn->sign & ~DECIMAL_NEG)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (DEC_HI32(pdecIn) || DEC_MID32(pdecIn) & 0x80000000)
|
||||
if (pdecIn->Hi32 || pdecIn->Mid32 & 0x80000000)
|
||||
return DISP_E_OVERFLOW;
|
||||
|
||||
if (DEC_SIGN(pdecIn))
|
||||
*pi64Out = -DEC_LO64(pdecIn);
|
||||
if (pdecIn->sign)
|
||||
*pi64Out = -pdecIn->Lo64;
|
||||
else
|
||||
*pi64Out = DEC_LO64(pdecIn);
|
||||
*pi64Out = pdecIn->Lo64;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
|
@ -2504,9 +2501,9 @@ HRESULT WINAPI VarUI8FromCy(CY cyIn, ULONG64* pui64Out)
|
|||
{
|
||||
*pui64Out = cyIn.int64 / CY_MULTIPLIER;
|
||||
|
||||
cyIn.int64 -= *pui64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */
|
||||
cyIn.int64 -= *pui64Out * CY_MULTIPLIER; /* cyIn.Lo now holds fractional remainder */
|
||||
|
||||
if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pui64Out & 0x1)))
|
||||
if (cyIn.Lo > CY_HALF || (cyIn.Lo == CY_HALF && (*pui64Out & 0x1)))
|
||||
(*pui64Out)++;
|
||||
}
|
||||
return S_OK;
|
||||
|
@ -2666,22 +2663,22 @@ HRESULT WINAPI VarUI8FromUI4(ULONG ulIn, ULONG64* pui64Out)
|
|||
*/
|
||||
HRESULT WINAPI VarUI8FromDec(const DECIMAL *pdecIn, ULONG64* pui64Out)
|
||||
{
|
||||
if (!DEC_SCALE(pdecIn))
|
||||
if (!pdecIn->scale)
|
||||
{
|
||||
/* This decimal is just a 96 bit integer */
|
||||
if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
|
||||
if (pdecIn->sign & ~DECIMAL_NEG)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (DEC_HI32(pdecIn))
|
||||
if (pdecIn->Hi32)
|
||||
return DISP_E_OVERFLOW;
|
||||
|
||||
if (DEC_SIGN(pdecIn))
|
||||
if (pdecIn->sign)
|
||||
{
|
||||
WARN("Sign would be ignored under Win32!\n");
|
||||
return DISP_E_OVERFLOW;
|
||||
}
|
||||
|
||||
*pui64Out = DEC_LO64(pdecIn);
|
||||
*pui64Out = pdecIn->Lo64;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
|
@ -2942,29 +2939,29 @@ HRESULT WINAPI VarR4FromUI4(ULONG ulIn, float *pFltOut)
|
|||
*/
|
||||
HRESULT WINAPI VarR4FromDec(const DECIMAL* pDecIn, float *pFltOut)
|
||||
{
|
||||
BYTE scale = DEC_SCALE(pDecIn);
|
||||
BYTE scale = pDecIn->scale;
|
||||
double divisor = 1.0;
|
||||
double highPart;
|
||||
|
||||
if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
|
||||
if (scale > DEC_MAX_SCALE || pDecIn->sign & ~DECIMAL_NEG)
|
||||
return E_INVALIDARG;
|
||||
|
||||
while (scale--)
|
||||
divisor *= 10.0;
|
||||
|
||||
if (DEC_SIGN(pDecIn))
|
||||
if (pDecIn->sign)
|
||||
divisor = -divisor;
|
||||
|
||||
if (DEC_HI32(pDecIn))
|
||||
if (pDecIn->Hi32)
|
||||
{
|
||||
highPart = (double)DEC_HI32(pDecIn) / divisor;
|
||||
highPart = (double)pDecIn->Hi32 / divisor;
|
||||
highPart *= 4294967296.0F;
|
||||
highPart *= 4294967296.0F;
|
||||
}
|
||||
else
|
||||
highPart = 0.0;
|
||||
|
||||
*pFltOut = (double)DEC_LO64(pDecIn) / divisor + highPart;
|
||||
*pFltOut = (double)pDecIn->Lo64 / divisor + highPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -3263,28 +3260,28 @@ HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double *pDblOut)
|
|||
*/
|
||||
HRESULT WINAPI VarR8FromDec(const DECIMAL* pDecIn, double *pDblOut)
|
||||
{
|
||||
BYTE scale = DEC_SCALE(pDecIn);
|
||||
BYTE scale = pDecIn->scale;
|
||||
double divisor = 1.0, highPart;
|
||||
|
||||
if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
|
||||
if (scale > DEC_MAX_SCALE || pDecIn->sign & ~DECIMAL_NEG)
|
||||
return E_INVALIDARG;
|
||||
|
||||
while (scale--)
|
||||
divisor *= 10;
|
||||
|
||||
if (DEC_SIGN(pDecIn))
|
||||
if (pDecIn->sign)
|
||||
divisor = -divisor;
|
||||
|
||||
if (DEC_HI32(pDecIn))
|
||||
if (pDecIn->Hi32)
|
||||
{
|
||||
highPart = (double)DEC_HI32(pDecIn) / divisor;
|
||||
highPart = (double)pDecIn->Hi32 / divisor;
|
||||
highPart *= 4294967296.0F;
|
||||
highPart *= 4294967296.0F;
|
||||
}
|
||||
else
|
||||
highPart = 0.0;
|
||||
|
||||
*pDblOut = (double)DEC_LO64(pDecIn) / divisor + highPart;
|
||||
*pDblOut = (double)pDecIn->Lo64 / divisor + highPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -3709,12 +3706,12 @@ HRESULT WINAPI VarCyFromDec(const DECIMAL* pdecIn, CY* pCyOut)
|
|||
{
|
||||
double d;
|
||||
|
||||
if (DEC_HI32(&rounded))
|
||||
if (rounded.Hi32)
|
||||
return DISP_E_OVERFLOW;
|
||||
|
||||
/* Note: Without the casts this promotes to int64 which loses precision */
|
||||
d = (double)DEC_LO64(&rounded) / (double)CY_Divisors[DEC_SCALE(&rounded)];
|
||||
if (DEC_SIGN(&rounded))
|
||||
d = (double)rounded.Lo64 / (double)CY_Divisors[rounded.scale];
|
||||
if (rounded.sign)
|
||||
d = -d;
|
||||
return VarCyFromR8(d, pCyOut);
|
||||
}
|
||||
|
@ -3872,7 +3869,7 @@ HRESULT WINAPI VarCySub(CY cyLeft, CY cyRight, CY* pCyOut)
|
|||
*/
|
||||
HRESULT WINAPI VarCyAbs(CY cyIn, CY* pCyOut)
|
||||
{
|
||||
if (cyIn.s.Hi == 0x80000000 && !cyIn.s.Lo)
|
||||
if (cyIn.Hi == 0x80000000 && !cyIn.Lo)
|
||||
return DISP_E_OVERFLOW;
|
||||
|
||||
pCyOut->int64 = cyIn.int64 < 0 ? -cyIn.int64 : cyIn.int64;
|
||||
|
@ -3947,7 +3944,7 @@ HRESULT WINAPI VarCyInt(CY cyIn, CY* pCyOut)
|
|||
*/
|
||||
HRESULT WINAPI VarCyNeg(CY cyIn, CY* pCyOut)
|
||||
{
|
||||
if (cyIn.s.Hi == 0x80000000 && !cyIn.s.Lo)
|
||||
if (cyIn.Hi == 0x80000000 && !cyIn.Lo)
|
||||
return DISP_E_OVERFLOW;
|
||||
|
||||
pCyOut->int64 = -cyIn.int64;
|
||||
|
@ -4127,18 +4124,19 @@ HRESULT WINAPI VarDecFromI2(SHORT sIn, DECIMAL* pDecOut)
|
|||
*/
|
||||
HRESULT WINAPI VarDecFromI4(LONG lIn, DECIMAL* pDecOut)
|
||||
{
|
||||
DEC_HI32(pDecOut) = 0;
|
||||
DEC_MID32(pDecOut) = 0;
|
||||
pDecOut->Hi32 = 0;
|
||||
pDecOut->Mid32 = 0;
|
||||
pDecOut->scale = 0;
|
||||
|
||||
if (lIn < 0)
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0);
|
||||
DEC_LO32(pDecOut) = -lIn;
|
||||
pDecOut->sign = DECIMAL_NEG;
|
||||
pDecOut->Lo32 = -lIn;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_LO32(pDecOut) = lIn;
|
||||
pDecOut->sign = DECIMAL_POS;
|
||||
pDecOut->Lo32 = lIn;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -4235,19 +4233,18 @@ HRESULT WINAPI VarDecFromDate(DATE dateIn, DECIMAL* pDecOut)
|
|||
*/
|
||||
HRESULT WINAPI VarDecFromCy(CY cyIn, DECIMAL* pDecOut)
|
||||
{
|
||||
DEC_HI32(pDecOut) = 0;
|
||||
pDecOut->Hi32 = 0;
|
||||
pDecOut->scale = 4;
|
||||
|
||||
/* Note: This assumes 2s complement integer representation */
|
||||
if (cyIn.s.Hi & 0x80000000)
|
||||
if (cyIn.int64 < 0)
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,4);
|
||||
DEC_LO64(pDecOut) = -cyIn.int64;
|
||||
pDecOut->sign = DECIMAL_NEG;
|
||||
pDecOut->Lo64 = -cyIn.int64;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,4);
|
||||
DEC_MID32(pDecOut) = cyIn.s.Hi;
|
||||
DEC_LO32(pDecOut) = cyIn.s.Lo;
|
||||
pDecOut->sign = DECIMAL_POS;
|
||||
pDecOut->Lo64 = cyIn.int64;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -4308,17 +4305,17 @@ HRESULT WINAPI VarDecFromDisp(IDispatch* pdispIn, LCID lcid, DECIMAL* pDecOut)
|
|||
*/
|
||||
HRESULT WINAPI VarDecFromBool(VARIANT_BOOL bIn, DECIMAL* pDecOut)
|
||||
{
|
||||
DEC_HI32(pDecOut) = 0;
|
||||
DEC_MID32(pDecOut) = 0;
|
||||
pDecOut->Hi32 = 0;
|
||||
pDecOut->scale = 0;
|
||||
if (bIn)
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0);
|
||||
DEC_LO32(pDecOut) = 1;
|
||||
pDecOut->sign = DECIMAL_NEG;
|
||||
pDecOut->Lo64 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_LO32(pDecOut) = 0;
|
||||
pDecOut->sign = DECIMAL_POS;
|
||||
pDecOut->Lo64 = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -4371,11 +4368,11 @@ HRESULT WINAPI VarDecFromUI2(USHORT usIn, DECIMAL* pDecOut)
|
|||
*/
|
||||
HRESULT WINAPI VarDecFromUI4(ULONG ulIn, DECIMAL* pDecOut)
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_HI32(pDecOut) = 0;
|
||||
DEC_MID32(pDecOut) = 0;
|
||||
DEC_LO32(pDecOut) = ulIn;
|
||||
return S_OK;
|
||||
pDecOut->sign = DECIMAL_POS;
|
||||
pDecOut->scale = 0;
|
||||
pDecOut->Hi32 = 0;
|
||||
pDecOut->Lo64 = ulIn;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -4392,23 +4389,20 @@ HRESULT WINAPI VarDecFromUI4(ULONG ulIn, DECIMAL* pDecOut)
|
|||
*/
|
||||
HRESULT WINAPI VarDecFromI8(LONG64 llIn, DECIMAL* pDecOut)
|
||||
{
|
||||
PULARGE_INTEGER pLi = (PULARGE_INTEGER)&llIn;
|
||||
pDecOut->Hi32 = 0;
|
||||
pDecOut->scale = 0;
|
||||
|
||||
DEC_HI32(pDecOut) = 0;
|
||||
|
||||
/* Note: This assumes 2s complement integer representation */
|
||||
if (pLi->u.HighPart & 0x80000000)
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0);
|
||||
DEC_LO64(pDecOut) = -pLi->QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_MID32(pDecOut) = pLi->u.HighPart;
|
||||
DEC_LO32(pDecOut) = pLi->u.LowPart;
|
||||
}
|
||||
return S_OK;
|
||||
if (llIn < 0)
|
||||
{
|
||||
pDecOut->sign = DECIMAL_NEG;
|
||||
pDecOut->Lo64 = -llIn;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDecOut->sign = DECIMAL_POS;
|
||||
pDecOut->Lo64 = llIn;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -4425,10 +4419,11 @@ HRESULT WINAPI VarDecFromI8(LONG64 llIn, DECIMAL* pDecOut)
|
|||
*/
|
||||
HRESULT WINAPI VarDecFromUI8(ULONG64 ullIn, DECIMAL* pDecOut)
|
||||
{
|
||||
DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
|
||||
DEC_HI32(pDecOut) = 0;
|
||||
DEC_LO64(pDecOut) = ullIn;
|
||||
return S_OK;
|
||||
pDecOut->sign = DECIMAL_POS;
|
||||
pDecOut->scale = 0;
|
||||
pDecOut->Hi32 = 0;
|
||||
pDecOut->Lo64 = ullIn;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Make two DECIMALS the same scale; used by math functions below */
|
||||
|
@ -4442,12 +4437,12 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
|
|||
VARIANT_DI di;
|
||||
int scaleAmount, i;
|
||||
|
||||
if (DEC_SIGN(*ppDecLeft) & ~DECIMAL_NEG || DEC_SIGN(*ppDecRight) & ~DECIMAL_NEG)
|
||||
if ((*ppDecLeft)->sign & ~DECIMAL_NEG || (*ppDecRight)->sign & ~DECIMAL_NEG)
|
||||
return E_INVALIDARG;
|
||||
|
||||
DEC_LO32(&scaleFactor) = 10;
|
||||
scaleFactor.Lo32 = 10;
|
||||
|
||||
i = scaleAmount = DEC_SCALE(*ppDecLeft) - DEC_SCALE(*ppDecRight);
|
||||
i = scaleAmount = (*ppDecLeft)->scale - (*ppDecRight)->scale;
|
||||
|
||||
if (!scaleAmount)
|
||||
return S_OK; /* Same scale */
|
||||
|
@ -4473,7 +4468,7 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
|
|||
|
||||
if (!i)
|
||||
{
|
||||
DEC_SCALE(&pDecOut[0]) += (scaleAmount > 0) ? scaleAmount : (-scaleAmount);
|
||||
pDecOut[0].scale += (scaleAmount > 0) ? scaleAmount : (-scaleAmount);
|
||||
return S_OK; /* Same scale */
|
||||
}
|
||||
|
||||
|
@ -4481,13 +4476,13 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
|
|||
pDecOut[0] = decTemp;
|
||||
if (scaleAmount > 0)
|
||||
{
|
||||
DEC_SCALE(&pDecOut[0]) += scaleAmount - i;
|
||||
pDecOut[0].scale += scaleAmount - i;
|
||||
VARIANT_DIFromDec(*ppDecLeft, &di);
|
||||
*ppDecLeft = &pDecOut[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
DEC_SCALE(&pDecOut[0]) += (-scaleAmount) - i;
|
||||
pDecOut[0].scale += (-scaleAmount) - i;
|
||||
VARIANT_DIFromDec(*ppDecRight, &di);
|
||||
*ppDecRight = &pDecOut[1];
|
||||
}
|
||||
|
@ -4519,8 +4514,8 @@ static ULONG VARIANT_Add(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh)
|
|||
ULARGE_INTEGER ul64;
|
||||
|
||||
ul64.QuadPart = (ULONG64)ulLeft + (ULONG64)ulRight + (ULONG64)*pulHigh;
|
||||
*pulHigh = ul64.u.HighPart;
|
||||
return ul64.u.LowPart;
|
||||
*pulHigh = ul64.HighPart;
|
||||
return ul64.LowPart;
|
||||
}
|
||||
|
||||
/* Subtract two unsigned 32 bit values with underflow */
|
||||
|
@ -4541,10 +4536,10 @@ static ULONG VARIANT_Sub(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh)
|
|||
invert = TRUE;
|
||||
}
|
||||
if (invert)
|
||||
ul64.u.HighPart = -ul64.u.HighPart ;
|
||||
ul64.HighPart = -ul64.HighPart ;
|
||||
|
||||
*pulHigh = ul64.u.HighPart;
|
||||
return ul64.u.LowPart;
|
||||
*pulHigh = ul64.HighPart;
|
||||
return ul64.LowPart;
|
||||
}
|
||||
|
||||
/* Multiply two unsigned 32 bit values with overflow */
|
||||
|
@ -4553,17 +4548,17 @@ static ULONG VARIANT_Mul(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh)
|
|||
ULARGE_INTEGER ul64;
|
||||
|
||||
ul64.QuadPart = (ULONG64)ulLeft * (ULONG64)ulRight + (ULONG64)*pulHigh;
|
||||
*pulHigh = ul64.u.HighPart;
|
||||
return ul64.u.LowPart;
|
||||
*pulHigh = ul64.HighPart;
|
||||
return ul64.LowPart;
|
||||
}
|
||||
|
||||
/* Compare two decimals that have the same scale */
|
||||
static inline int VARIANT_DecCmp(const DECIMAL *pDecLeft, const DECIMAL *pDecRight)
|
||||
{
|
||||
if ( DEC_HI32(pDecLeft) < DEC_HI32(pDecRight) ||
|
||||
(DEC_HI32(pDecLeft) <= DEC_HI32(pDecRight) && DEC_LO64(pDecLeft) < DEC_LO64(pDecRight)))
|
||||
if ( pDecLeft->Hi32 < pDecRight->Hi32 ||
|
||||
(pDecLeft->Hi32 <= pDecRight->Hi32 && pDecLeft->Lo64 < pDecRight->Lo64))
|
||||
return -1;
|
||||
else if (DEC_HI32(pDecLeft) == DEC_HI32(pDecRight) && DEC_LO64(pDecLeft) == DEC_LO64(pDecRight))
|
||||
else if (pDecLeft->Hi32 == pDecRight->Hi32 && pDecLeft->Lo64 == pDecRight->Lo64)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -4597,13 +4592,13 @@ HRESULT WINAPI VarDecAdd(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI
|
|||
int cmp;
|
||||
|
||||
/* Correct for the sign of the result */
|
||||
if (DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight))
|
||||
if (pDecLeft->sign && pDecRight->sign)
|
||||
{
|
||||
/* -x + -y : Negative */
|
||||
sign = DECIMAL_NEG;
|
||||
goto VarDecAdd_AsPositive;
|
||||
}
|
||||
else if (DEC_SIGN(pDecLeft) && !DEC_SIGN(pDecRight))
|
||||
else if (pDecLeft->sign && !pDecRight->sign)
|
||||
{
|
||||
cmp = VARIANT_DecCmp(pDecLeft, pDecRight);
|
||||
|
||||
|
@ -4612,19 +4607,19 @@ HRESULT WINAPI VarDecAdd(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI
|
|||
{
|
||||
sign = DECIMAL_NEG;
|
||||
VarDecAdd_AsNegative:
|
||||
DEC_LO32(pDecOut) = VARIANT_Sub(DEC_LO32(pDecLeft), DEC_LO32(pDecRight), &overflow);
|
||||
DEC_MID32(pDecOut) = VARIANT_Sub(DEC_MID32(pDecLeft), DEC_MID32(pDecRight), &overflow);
|
||||
DEC_HI32(pDecOut) = VARIANT_Sub(DEC_HI32(pDecLeft), DEC_HI32(pDecRight), &overflow);
|
||||
pDecOut->Lo32 = VARIANT_Sub(pDecLeft->Lo32, pDecRight->Lo32, &overflow);
|
||||
pDecOut->Mid32 = VARIANT_Sub(pDecLeft->Mid32, pDecRight->Mid32, &overflow);
|
||||
pDecOut->Hi32 = VARIANT_Sub(pDecLeft->Hi32, pDecRight->Hi32, &overflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
VarDecAdd_AsInvertedNegative:
|
||||
DEC_LO32(pDecOut) = VARIANT_Sub(DEC_LO32(pDecRight), DEC_LO32(pDecLeft), &overflow);
|
||||
DEC_MID32(pDecOut) = VARIANT_Sub(DEC_MID32(pDecRight), DEC_MID32(pDecLeft), &overflow);
|
||||
DEC_HI32(pDecOut) = VARIANT_Sub(DEC_HI32(pDecRight), DEC_HI32(pDecLeft), &overflow);
|
||||
pDecOut->Lo32 = VARIANT_Sub(pDecRight->Lo32, pDecLeft->Lo32, &overflow);
|
||||
pDecOut->Mid32 = VARIANT_Sub(pDecRight->Mid32, pDecLeft->Mid32, &overflow);
|
||||
pDecOut->Hi32 = VARIANT_Sub(pDecRight->Hi32, pDecLeft->Hi32, &overflow);
|
||||
}
|
||||
}
|
||||
else if (!DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight))
|
||||
else if (!pDecLeft->sign && pDecRight->sign)
|
||||
{
|
||||
cmp = VARIANT_DecCmp(pDecLeft, pDecRight);
|
||||
|
||||
|
@ -4640,9 +4635,9 @@ VarDecAdd_AsInvertedNegative:
|
|||
{
|
||||
/* x + y : Positive */
|
||||
VarDecAdd_AsPositive:
|
||||
DEC_LO32(pDecOut) = VARIANT_Add(DEC_LO32(pDecLeft), DEC_LO32(pDecRight), &overflow);
|
||||
DEC_MID32(pDecOut) = VARIANT_Add(DEC_MID32(pDecLeft), DEC_MID32(pDecRight), &overflow);
|
||||
DEC_HI32(pDecOut) = VARIANT_Add(DEC_HI32(pDecLeft), DEC_HI32(pDecRight), &overflow);
|
||||
pDecOut->Lo32 = VARIANT_Add(pDecLeft->Lo32, pDecRight->Lo32, &overflow);
|
||||
pDecOut->Mid32 = VARIANT_Add(pDecLeft->Mid32, pDecRight->Mid32, &overflow);
|
||||
pDecOut->Hi32 = VARIANT_Add(pDecLeft->Hi32, pDecRight->Hi32, &overflow);
|
||||
|
||||
if (overflow)
|
||||
{
|
||||
|
@ -4650,15 +4645,15 @@ VarDecAdd_AsPositive:
|
|||
DWORD n[4];
|
||||
unsigned char remainder;
|
||||
|
||||
if (!DEC_SCALE(pDecLeft))
|
||||
if (!pDecLeft->scale)
|
||||
return DISP_E_OVERFLOW;
|
||||
|
||||
DEC_SCALE(pDecOut) = DEC_SCALE(pDecLeft) - 1;
|
||||
DEC_SIGN(pDecOut) = sign;
|
||||
pDecOut->scale = pDecLeft->scale - 1;
|
||||
pDecOut->sign = sign;
|
||||
|
||||
n[0] = DEC_LO32(pDecOut);
|
||||
n[1] = DEC_MID32(pDecOut);
|
||||
n[2] = DEC_HI32(pDecOut);
|
||||
n[0] = pDecOut->Lo32;
|
||||
n[1] = pDecOut->Mid32;
|
||||
n[2] = pDecOut->Hi32;
|
||||
n[3] = overflow;
|
||||
|
||||
remainder = VARIANT_int_divbychar(n,4,10);
|
||||
|
@ -4674,9 +4669,9 @@ VarDecAdd_AsPositive:
|
|||
}
|
||||
}
|
||||
|
||||
DEC_LO32(pDecOut) = n[0] ;
|
||||
DEC_MID32(pDecOut) = n[1];
|
||||
DEC_HI32(pDecOut) = n[2];
|
||||
pDecOut->Lo32 = n[0] ;
|
||||
pDecOut->Mid32 = n[1];
|
||||
pDecOut->Hi32 = n[2];
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -4685,8 +4680,8 @@ VarDecAdd_AsPositive:
|
|||
if (overflow)
|
||||
return DISP_E_OVERFLOW; /* overflowed */
|
||||
|
||||
DEC_SCALE(pDecOut) = DEC_SCALE(pDecLeft);
|
||||
DEC_SIGN(pDecOut) = sign;
|
||||
pDecOut->scale = pDecLeft->scale;
|
||||
pDecOut->sign = sign;
|
||||
}
|
||||
return hRet;
|
||||
}
|
||||
|
@ -4694,25 +4689,21 @@ VarDecAdd_AsPositive:
|
|||
/* translate from external DECIMAL format into an internal representation */
|
||||
static void VARIANT_DIFromDec(const DECIMAL * from, VARIANT_DI * to)
|
||||
{
|
||||
to->scale = DEC_SCALE(from);
|
||||
to->sign = DEC_SIGN(from) ? 1 : 0;
|
||||
to->scale = from->scale;
|
||||
to->sign = from->sign ? 1 : 0;
|
||||
|
||||
to->bitsnum[0] = DEC_LO32(from);
|
||||
to->bitsnum[1] = DEC_MID32(from);
|
||||
to->bitsnum[2] = DEC_HI32(from);
|
||||
to->bitsnum[0] = from->Lo32;
|
||||
to->bitsnum[1] = from->Mid32;
|
||||
to->bitsnum[2] = from->Hi32;
|
||||
}
|
||||
|
||||
static void VARIANT_DecFromDI(const VARIANT_DI * from, DECIMAL * to)
|
||||
{
|
||||
if (from->sign) {
|
||||
DEC_SIGNSCALE(to) = SIGNSCALE(DECIMAL_NEG, from->scale);
|
||||
} else {
|
||||
DEC_SIGNSCALE(to) = SIGNSCALE(DECIMAL_POS, from->scale);
|
||||
}
|
||||
|
||||
DEC_LO32(to) = from->bitsnum[0];
|
||||
DEC_MID32(to) = from->bitsnum[1];
|
||||
DEC_HI32(to) = from->bitsnum[2];
|
||||
to->sign = from->sign ? DECIMAL_NEG : DECIMAL_POS;
|
||||
to->scale = from->scale;
|
||||
to->Lo32 = from->bitsnum[0];
|
||||
to->Mid32 = from->bitsnum[1];
|
||||
to->Hi32 = from->bitsnum[2];
|
||||
}
|
||||
|
||||
/* clear an internal representation of a DECIMAL */
|
||||
|
@ -5732,7 +5723,7 @@ HRESULT WINAPI VarDecSub(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI
|
|||
HRESULT WINAPI VarDecAbs(const DECIMAL* pDecIn, DECIMAL* pDecOut)
|
||||
{
|
||||
*pDecOut = *pDecIn;
|
||||
DEC_SIGN(pDecOut) &= ~DECIMAL_NEG;
|
||||
pDecOut->sign &= ~DECIMAL_NEG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -5758,10 +5749,10 @@ HRESULT WINAPI VarDecFix(const DECIMAL* pDecIn, DECIMAL* pDecOut)
|
|||
double dbl;
|
||||
HRESULT hr;
|
||||
|
||||
if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
|
||||
if (pDecIn->sign & ~DECIMAL_NEG)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!DEC_SCALE(pDecIn))
|
||||
if (!pDecIn->scale)
|
||||
{
|
||||
*pDecOut = *pDecIn; /* Already an integer */
|
||||
return S_OK;
|
||||
|
@ -5798,10 +5789,10 @@ HRESULT WINAPI VarDecInt(const DECIMAL* pDecIn, DECIMAL* pDecOut)
|
|||
double dbl;
|
||||
HRESULT hr;
|
||||
|
||||
if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
|
||||
if (pDecIn->sign & ~DECIMAL_NEG)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!(DEC_SIGN(pDecIn) & DECIMAL_NEG) || !DEC_SCALE(pDecIn))
|
||||
if (!(pDecIn->sign & DECIMAL_NEG) || !pDecIn->scale)
|
||||
return VarDecFix(pDecIn, pDecOut); /* The same, if +ve or no fractionals */
|
||||
|
||||
hr = VarR8FromDec(pDecIn, &dbl);
|
||||
|
@ -5828,7 +5819,7 @@ HRESULT WINAPI VarDecInt(const DECIMAL* pDecIn, DECIMAL* pDecOut)
|
|||
HRESULT WINAPI VarDecNeg(const DECIMAL* pDecIn, DECIMAL* pDecOut)
|
||||
{
|
||||
*pDecOut = *pDecIn;
|
||||
DEC_SIGN(pDecOut) ^= DECIMAL_NEG;
|
||||
pDecOut->sign ^= DECIMAL_NEG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -5852,10 +5843,10 @@ HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOu
|
|||
HRESULT hr;
|
||||
unsigned int i;
|
||||
|
||||
if (cDecimals < 0 || (DEC_SIGN(pDecIn) & ~DECIMAL_NEG) || DEC_SCALE(pDecIn) > DEC_MAX_SCALE)
|
||||
if (cDecimals < 0 || (pDecIn->sign & ~DECIMAL_NEG) || pDecIn->scale > DEC_MAX_SCALE)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (cDecimals >= DEC_SCALE(pDecIn))
|
||||
if (cDecimals >= pDecIn->scale)
|
||||
{
|
||||
*pDecOut = *pDecIn; /* More precision than we have */
|
||||
return S_OK;
|
||||
|
@ -5863,11 +5854,11 @@ HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOu
|
|||
|
||||
/* truncate significant digits and rescale */
|
||||
memset(&divisor, 0, sizeof(divisor));
|
||||
DEC_LO64(&divisor) = 1;
|
||||
divisor.Lo64 = 1;
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
DEC_LO64(&tmp) = 10;
|
||||
for (i = 0; i < DEC_SCALE(pDecIn) - cDecimals; ++i)
|
||||
tmp.Lo64 = 10;
|
||||
for (i = 0; i < pDecIn->scale - cDecimals; ++i)
|
||||
{
|
||||
hr = VarDecMul(&divisor, &tmp, &divisor);
|
||||
if (FAILED(hr))
|
||||
|
@ -5878,7 +5869,7 @@ HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOu
|
|||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
DEC_SCALE(pDecOut) = cDecimals;
|
||||
pDecOut->scale = cDecimals;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -5905,11 +5896,11 @@ HRESULT WINAPI VarDecCmp(const DECIMAL* pDecLeft, const DECIMAL* pDecRight)
|
|||
if (!pDecLeft || !pDecRight)
|
||||
return VARCMP_NULL;
|
||||
|
||||
if ((!(DEC_SIGN(pDecLeft) & DECIMAL_NEG)) && (DEC_SIGN(pDecRight) & DECIMAL_NEG) &&
|
||||
(DEC_HI32(pDecLeft) | DEC_MID32(pDecLeft) | DEC_LO32(pDecLeft)))
|
||||
if ((!(pDecLeft->sign & DECIMAL_NEG)) && (pDecRight->sign & DECIMAL_NEG) &&
|
||||
(pDecLeft->Hi32 || pDecLeft->Lo64))
|
||||
return VARCMP_GT;
|
||||
else if ((DEC_SIGN(pDecLeft) & DECIMAL_NEG) && (!(DEC_SIGN(pDecRight) & DECIMAL_NEG)) &&
|
||||
(DEC_HI32(pDecLeft) | DEC_MID32(pDecLeft) | DEC_LO32(pDecLeft)))
|
||||
else if ((pDecLeft->sign & DECIMAL_NEG) && (!(pDecRight->sign & DECIMAL_NEG)) &&
|
||||
(pDecLeft->Hi32 || pDecLeft->Lo64))
|
||||
return VARCMP_LT;
|
||||
|
||||
/* Subtract right from left, and compare the result to 0 */
|
||||
|
@ -5917,9 +5908,9 @@ HRESULT WINAPI VarDecCmp(const DECIMAL* pDecLeft, const DECIMAL* pDecRight)
|
|||
|
||||
if (SUCCEEDED(hRet))
|
||||
{
|
||||
int non_zero = DEC_HI32(&result) | DEC_MID32(&result) | DEC_LO32(&result);
|
||||
int non_zero = result.Hi32 || result.Lo64;
|
||||
|
||||
if ((DEC_SIGN(&result) & DECIMAL_NEG) && non_zero)
|
||||
if ((result.sign & DECIMAL_NEG) && non_zero)
|
||||
hRet = (HRESULT)VARCMP_LT;
|
||||
else if (non_zero)
|
||||
hRet = (HRESULT)VARCMP_GT;
|
||||
|
@ -6308,10 +6299,10 @@ HRESULT WINAPI VarBoolFromUI4(ULONG ulIn, VARIANT_BOOL *pBoolOut)
|
|||
*/
|
||||
HRESULT WINAPI VarBoolFromDec(const DECIMAL* pDecIn, VARIANT_BOOL *pBoolOut)
|
||||
{
|
||||
if (DEC_SCALE(pDecIn) > DEC_MAX_SCALE || (DEC_SIGN(pDecIn) & ~DECIMAL_NEG))
|
||||
if (pDecIn->scale > DEC_MAX_SCALE || (pDecIn->sign & ~DECIMAL_NEG))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (DEC_HI32(pDecIn) || DEC_MID32(pDecIn) || DEC_LO32(pDecIn))
|
||||
if (pDecIn->Hi32 || pDecIn->Lo64)
|
||||
*pBoolOut = VARIANT_TRUE;
|
||||
else
|
||||
*pBoolOut = VARIANT_FALSE;
|
||||
|
@ -6650,9 +6641,9 @@ HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
|
|||
|
||||
decVal.scale = 4;
|
||||
decVal.sign = 0;
|
||||
decVal.bitsnum[0] = cyIn.s.Lo;
|
||||
decVal.bitsnum[1] = cyIn.s.Hi;
|
||||
if (cyIn.s.Hi & 0x80000000UL) {
|
||||
decVal.bitsnum[0] = cyIn.Lo;
|
||||
decVal.bitsnum[1] = cyIn.Hi;
|
||||
if (cyIn.Hi & 0x80000000UL) {
|
||||
DWORD one = 1;
|
||||
|
||||
/* Negative number! */
|
||||
|
|
Loading…
Add table
Reference in a new issue