다음을 통해 공유


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 표준의 일부입니다.