VarI8FromCy는 CY 값이 클 때 잘못된 값을 생성합니다.
이 문서에서는 CY(통화) 형식을 8 바이트(64비트) 정수로 변환하기 위한 OLE Automation 함수의 문제를 설명합니다.
원래 제품 버전: Windows
원본 KB 번호: 2282810
증상
, VariantChangeTypeEx
또는 를 사용하여 VariantChangeType
큰 (>429497.0) 또는 음의 통화 값을 64비트 정수(예: I8 long
또는 int64
)로 변환하는 애플리케이션은 1씩 해제된 결과 정수 값을 VarI8FromCy
가져올 수 있습니다.
원인
논리에는 통화 값이 Hi 부분에 0을 제외한 모든 값이 있을 때 모든 값이 0에서 반올림되는 알려진 결함이 있습니다.
해결 방법
이러한 함수에 대한 사용자 고유의 대체를 사용하여 올바른 논리를 구현합니다.
참고
이 동일한 해결 방법을 구현하지 않은 다른 구성 요소와 상호 운용하는 경우 사용자(또는 최종 사용자)가 다르거나 혼란스러운 결과를 얻을 수 있습니다.
이 작업을 수행하는 데 적합한 몇 가지 함수의 예는 다음과 같습니다. 이 경우 코드 대신 VariantChangeType(Ex)
를 호출 MyVariantChangeType(Ex)
합니다. 그리고 에 대한 직접 호출을 VarI8FromCy
대신 에 대한 호출로 MyVarI8FromCy
대체합니다.
STDAPI MyVarI8FromCy( CY cyIn, __int64 * pi64Out )
{
LONG64 lVal = cyIn.int64 / 10000;
LONG64 lDif = cyIn.int64 % 10000;
if ( lDif + (lVal & 1) > 5000 ) // IEEE rounding
{
if ( cyIn.Hi >= 0 )
lVal++;
else
lVal--;
}
*pi64Out = lVal;
return NOERROR;
}
STDAPI MyVariantChangeType( VARIANTARG * pvargDest, VARIANTARG * pvargSrc,
unsigned short wFlags, VARTYPE vt )
{
return MyVariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt );
}
STDAPI MyVariantChangeTypeEx( VARIANTARG * pvargDest, const VARIANTARG * pvargSrc, LCID lcid,
unsigned short wFlags, VARTYPE vt )
{
HRESULT hResult = E_FAIL;
if ( ( vt == VT_I8 )
&& ( V_VT(pvargSrc) == VT_CY )
)
hResult = MyVarI8FromCy( pvargSrc->cyVal, &pvargDest->llVal );
else
hResult = VariantChangeTypeEx( pvargDest, pvargSrc, lcid, wFlags, vt );
return hResult;
}
추가 정보
이 버그는 알려져 있지만 애플리케이션이 이 잘못된 동작에 종속되어 있으므로 지금 변경하면 이러한 애플리케이션이 중단된다는 증거가 있습니다.
일부는 위의 코드에서 (lVal & 1) 용어로 인해 혼동될 수 있습니다. 이는 정수 부분이 홀수일 때 정확히 .5 인 분수가 반올림되지만 정수 부분이 짝수이면 반올림되는 것을 제공하는 반올림을 위한 IEEE 표준의 일부입니다.