CY 값이 크면 VarI8FromCy에서 잘못된 값을 생성합니다.

  • 아티클
  • 2023. 07. 17.
  •  

이 문서의 내용

  1. 증상
  2. 원인
  3. 해결 방법
  4. 추가 정보

이 문서에서는 CY(통화) 형식을 8비트(64비트) 정수로 변환하기 위한 OLE Automation 함수의 문제를 설명합니다.

원래 제품 버전: Windows
원래 KB 번호: 2282810

증상

를 사용VariantChangeTypeVariantChangeTypeEx하거나 VarI8FromCy 큰(>429497.0) 또는 음의 통화 값을 64비트 정수(예: I8 long 또는int64)로 변환하는 애플리케이션은 1씩 해제된 결과 정수 값을 얻을 수 있습니다.

원인

통화 값이 Hi 부분에 0을 제외한 모든 값이 있으면 모든 값이 0에서 반올림되는 논리에 알려진 결함이 있습니다.

해결 방법

이러한 함수에 대한 사용자 고유의 대체를 사용하여 올바른 논리를 구현합니다.

참고

동일한 해결 방법을 구현하지 않은 다른 구성 요소와 상호 운용하는 경우 사용자(또는 최종 사용자)가 다르거나 혼동되는 결과를 얻을 수 있습니다.

다음은 이 작업을 수행하는 데 적합한 몇 가지 함수의 예입니다. 이 경우 코드 대신 VariantChangeType(Ex) 호출 MyVariantChangeType(Ex) 합니다. 그리고 직접 호출을 VarI8FromCy 대신 호출로 MyVarI8FromCy 대체합니다.

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

Posted by gurupia
,