MULDIV32.H
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (C) 1992 - 1997 Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. //  muldiv32.h
  13. //
  14. //  Description:
  15. //      math routines for 32 bit signed and unsiged numbers.
  16. //
  17. //      MulDiv32(a,b,c) = (a * b) / c         (round down, signed)
  18. //
  19. //      MulDivRD(a,b,c) = (a * b) / c         (round down, unsigned)
  20. //      MulDivRN(a,b,c) = (a * b + c/2) / c   (round nearest, unsigned)
  21. //      MulDivRU(a,b,c) = (a * b + c-1) / c   (round up, unsigned)
  22. //
  23. //==========================================================================;
  24. #ifndef _INC_MULDIV32
  25. #define _INC_MULDIV32
  26. #ifndef INLINE
  27. #define INLINE __inline
  28. #endif
  29. #ifdef WIN32
  30.     //----------------------------------------------------------------------;
  31.     //
  32.     //  Win 32
  33.     //
  34.     //----------------------------------------------------------------------;
  35.     #ifdef _X86_
  36.     
  37.         //
  38.         //  Use 32-bit x86 assembly.
  39.         //
  40.         #pragma warning(disable:4035 4704)
  41.         INLINE LONG MulDiv32(LONG a,LONG b,LONG c)
  42.         {
  43.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  44.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  45.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  46.             _asm     imul    ebx              //  imul ebx
  47.             _asm     idiv    ecx              //  idiv ecx
  48.             _asm  shld  edx, eax, 16     //  shld edx, eax, 16
  49.         } // MulDiv32()
  50.         INLINE DWORD MulDivRN(DWORD a,DWORD b,DWORD c)
  51.         {
  52.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  53.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  54.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  55.             _asm     mul     ebx              //  mul  ebx
  56.             _asm     mov     ebx,ecx          //  mov  ebx,ecx
  57.             _asm     shr     ebx,1            //  sar  ebx,1
  58.             _asm     add     eax,ebx          //  add  eax,ebx
  59.             _asm     adc     edx,0            //  adc  edx,0
  60.             _asm     div     ecx              //  div  ecx
  61.             _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  62.         } // MulDiv32()
  63.         INLINE DWORD MulDivRU(DWORD a,DWORD b,DWORD c)
  64.         {
  65.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  66.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  67.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  68.             _asm     mul     ebx              //  mul  ebx
  69.             _asm     mov     ebx,ecx          //  mov  ebx,ecx
  70.             _asm     dec     ebx              //  dec  ebx
  71.             _asm     add     eax,ebx          //  add  eax,ebx
  72.             _asm     adc     edx,0            //  adc  edx,0
  73.             _asm     div     ecx              //  div  ecx
  74.             _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  75.         } // MulDivRU32()
  76.         INLINE DWORD MulDivRD(DWORD a,DWORD b,DWORD c)
  77.         {
  78.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  79.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  80.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  81.             _asm     mul     ebx              //  mul  ebx
  82.             _asm     div     ecx              //  div  ecx
  83.             _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  84.         } // MulDivRD32()
  85.         #pragma warning(default:4035 4704)
  86.     #else
  87.         //
  88.         //  Use C9 __int64 support for Daytona RISC platforms.
  89.         //
  90.         INLINE LONG MulDiv32( LONG a, LONG b, LONG c )
  91.         {
  92.             return (LONG)( Int32x32To64(a,b) / c );
  93.         }
  94.         INLINE DWORD MulDivRD( DWORD a, DWORD b, DWORD c )
  95.         {
  96.             return (DWORD)( UInt32x32To64(a,b) / c );
  97.         }
  98.         INLINE DWORD MulDivRN( DWORD a, DWORD b, DWORD c )
  99.         {
  100.             return (DWORD)( (UInt32x32To64(a,b)+c/2) / c );
  101.         }
  102.         INLINE DWORD MulDivRU( DWORD a, DWORD b, DWORD c )
  103.         {
  104.             return (DWORD)( (UInt32x32To64(a,b)+c-1) / c );
  105.         }
  106.     #endif
  107. #else
  108.     //----------------------------------------------------------------------;
  109.     //
  110.     //  Win 16
  111.     //
  112.     //----------------------------------------------------------------------;
  113.     #pragma warning(disable:4035 4704)
  114.     //
  115.     //  Compile for 16-bit - we can use x86 with proper opcode prefixes
  116.     //     to get 32-bit instructions.
  117.     //
  118.     INLINE LONG MulDiv32(LONG a,LONG b,LONG c)
  119.     {
  120.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  121.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  122.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  123.         _asm _emit 0x66 _asm    imul    bx              //  imul ebx
  124.         _asm _emit 0x66 _asm    idiv    cx              //  idiv ecx
  125.         _asm _emit 0x66                                 //  shld edx, eax, 16
  126.         _asm _emit 0x0F
  127.         _asm _emit 0xA4
  128.         _asm _emit 0xC2
  129.         _asm _emit 0x10
  130.     } // MulDiv32()
  131.     INLINE DWORD MulDivRN(DWORD a,DWORD b,DWORD c)
  132.     {
  133.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  134.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  135.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  136.         _asm _emit 0x66 _asm    mul     bx              //  mul  ebx
  137.         _asm _emit 0x66 _asm    mov     bx,cx           //  mov  ebx,ecx
  138.         _asm _emit 0x66 _asm    shr     bx,1            //  sar  ebx,1
  139.         _asm _emit 0x66 _asm    add     ax,bx           //  add  eax,ebx
  140.         _asm _emit 0x66 _asm    adc     dx,0            //  adc  edx,0
  141.         _asm _emit 0x66 _asm    div     cx              //  div  ecx
  142.         _asm _emit 0x66                                 //  shld edx, eax, 16
  143.         _asm _emit 0x0F
  144.         _asm _emit 0xA4
  145.         _asm _emit 0xC2
  146.         _asm _emit 0x10
  147.     } // MulDiv32()
  148.     INLINE DWORD MulDivRU(DWORD a,DWORD b,DWORD c)
  149.     {
  150.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  151.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  152.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  153.         _asm _emit 0x66 _asm    mul     bx              //  mul  ebx
  154.         _asm _emit 0x66 _asm    mov     bx,cx           //  mov  ebx,ecx
  155.         _asm _emit 0x66 _asm    dec     bx              //  dec  ebx
  156.         _asm _emit 0x66 _asm    add     ax,bx           //  add  eax,ebx
  157.         _asm _emit 0x66 _asm    adc     dx,0            //  adc  edx,0
  158.         _asm _emit 0x66 _asm    div     cx              //  div  ecx
  159.         _asm _emit 0x66                                 //  shld edx, eax, 16
  160.         _asm _emit 0x0F
  161.         _asm _emit 0xA4
  162.         _asm _emit 0xC2
  163.         _asm _emit 0x10
  164.     } // MulDivRU32()
  165.     INLINE DWORD MulDivRD(DWORD a,DWORD b,DWORD c)
  166.     {
  167.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  168.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  169.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  170.         _asm _emit 0x66 _asm    mul     bx              //  mul  ebx
  171.         _asm _emit 0x66 _asm    div     cx              //  div  ecx
  172.         _asm _emit 0x66                                 //  shld edx, eax, 16
  173.         _asm _emit 0x0F
  174.         _asm _emit 0xA4
  175.         _asm _emit 0xC2
  176.         _asm _emit 0x10
  177.     } // MulDivRD32()
  178.     #pragma warning(default:4035 4704)
  179. #endif
  180. //
  181. //  some code references these by other names.
  182. //
  183. #define muldiv32    MulDivRN
  184. #define muldivrd32  MulDivRD
  185. #define muldivru32  MulDivRU
  186. #endif  // _INC_MULDIV32