home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / audio / mixapp / muldiv32.h < prev    next >
C/C++ Source or Header  |  1997-10-05  |  4KB  |  143 lines

  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.  
  25. #ifndef _INC_MULDIV32
  26. #define _INC_MULDIV32
  27.  
  28.  
  29. #ifndef INLINE
  30. #define INLINE __inline
  31. #endif
  32.  
  33.  
  34. #ifdef _X86_
  35.  
  36.     //
  37.     //  Use 32-bit x86 assembly.
  38.     //
  39.  
  40.     #pragma warning(disable:4035 4704)
  41.     #pragma optimize( "", off )    // Doesn't work with /Ox; MSVC20 messes up 
  42.                                 // the inline asm code, instead of including 
  43.                                 // it prolog/verbatim/epilog. 
  44.     #define MulDivRN MulDiv        // So use the Windows function for now
  45.     INLINE LONG MulDiv32(LONG a,LONG b,LONG c)
  46.     {
  47.         _asm     mov     eax,dword ptr a  //  mov  eax, a
  48.         _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  49.         _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  50.         _asm     imul    ebx              //  imul ebx
  51.         _asm     idiv    ecx              //  idiv ecx
  52.         _asm     shld     edx, eax, 16     //  shld edx, eax, 16
  53.  
  54.     } // MulDiv32()
  55.  
  56.     #if 0
  57.     INLINE DWORD MulDivRN(DWORD a,DWORD b,DWORD c)
  58.     {
  59.         _asm     mov     eax,dword ptr a  //  mov  eax, a
  60.         _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  61.         _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  62.         _asm     mul     ebx              //  mul  ebx
  63.         _asm     mov     ebx,ecx          //  mov  ebx,ecx
  64.         _asm     shr     ebx,1            //  sar  ebx,1
  65.         _asm     add     eax,ebx          //  add  eax,ebx
  66.         _asm     adc     edx,0            //  adc  edx,0
  67.         _asm     div     ecx              //  div  ecx
  68.         _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  69.  
  70.     } // MulDiv32()
  71.     #endif
  72.  
  73.     INLINE DWORD MulDivRU(DWORD a,DWORD b,DWORD c)
  74.     {
  75.         _asm     mov     eax,dword ptr a  //  mov  eax, a
  76.         _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  77.         _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  78.         _asm     mul     ebx              //  mul  ebx
  79.         _asm     mov     ebx,ecx          //  mov  ebx,ecx
  80.         _asm     dec     ebx              //  dec  ebx
  81.         _asm     add     eax,ebx          //  add  eax,ebx
  82.         _asm     adc     edx,0            //  adc  edx,0
  83.         _asm     div     ecx              //  div  ecx
  84.         _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  85.  
  86.     } // MulDivRU32()
  87.  
  88.     INLINE DWORD MulDivRD(DWORD a,DWORD b,DWORD c)
  89.     {
  90.         _asm     mov     eax,dword ptr a  //  mov  eax, a
  91.         _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  92.         _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  93.         _asm     mul     ebx              //  mul  ebx
  94.         _asm     div     ecx              //  div  ecx
  95.         _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  96.  
  97.     } // MulDivRD32()
  98.  
  99.     #pragma warning(default:4035 4704)
  100.     #pragma optimize( "", on )
  101.  
  102.  
  103. #else
  104.  
  105.     //
  106.     //  Use C9 __int64 support for Daytona RISC platforms.
  107.     //
  108.  
  109.     INLINE LONG MulDiv32( LONG a, LONG b, LONG c )
  110.     {
  111.         return (LONG)( Int32x32To64(a,b) / c );
  112.     }
  113.  
  114.  
  115.     INLINE DWORD MulDivRD( DWORD a, DWORD b, DWORD c )
  116.     {
  117.         return (DWORD)( UInt32x32To64(a,b) / c );
  118.     }
  119.  
  120.  
  121.     INLINE DWORD MulDivRN( DWORD a, DWORD b, DWORD c )
  122.     {
  123.         return (DWORD)( (UInt32x32To64(a,b)+c/2) / c );
  124.     }
  125.  
  126.  
  127.     INLINE DWORD MulDivRU( DWORD a, DWORD b, DWORD c )
  128.     {
  129.         return (DWORD)( (UInt32x32To64(a,b)+c-1) / c );
  130.     }
  131.  
  132. #endif
  133.  
  134.  
  135. //
  136. //  some code references these by other names.
  137. //
  138. #define muldiv32    MulDivRN
  139. #define muldivrd32  MulDivRD
  140. #define muldivru32  MulDivRU
  141.  
  142. #endif  // _INC_MULDIV32
  143.