MMMulDiv.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:13k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Fax.: +49 (0)351-8037944              =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 16.09.98 - 16:13:29 $                                        =}
  24. {========================================================================}
  25. Unit MMMulDiv;
  26. {$I COMPILER.INC}
  27. interface
  28. {$IFNDEF DELPHI4}
  29. uses MMUtils;
  30. {$ENDIF}
  31. function MulDiv32(a, b, c: Longint): Longint;
  32. function MulDiv32RN(a, b, c: Longint): Longint;
  33. function MulDivRN(a, b, c: Longint): Longint;
  34. function MulDivRU(a, b, c: Longint): Longint;
  35. function MulDivRD(a, b, c: Longint): Longint;
  36. function DivMod32(Dividend: Longint; Divisor: Word;
  37.                   Var _Div, _Mod: Word): Word;
  38. function Sal(value: Longint; Shift: Byte): Longint;
  39. function Sar(value: Longint; Shift: Byte): Longint;
  40. function RangeScale(Val, SrcMin, SrcMax, DstMin, DstMax: Longint): Longint;
  41. function RangeScaleRN(Val, SrcMin, SrcMax, DstMin, DstMax: Longint): Longint;
  42. function RangeScaleF(Val, SrcMin, SrcMax, DstMin, DstMax: Double): Double;
  43. {$IFDEF WIN32}
  44. function MulCompare(a,b,c,d: Longint): Boolean;
  45. {$ENDIF}
  46. function MulDiv64(a, b, c: int64): int64;
  47. implementation
  48. {************************************************************************}
  49. { function MulDiv32(a,b,c: Longint): Longint = (a * b) / c              *}
  50. {************************************************************************}
  51. function MulDiv32(a, b, c: Longint): Longint; assembler;
  52. asm
  53. {$IFDEF WIN32}
  54.    imul    edx
  55.    idiv    ecx
  56. {$ELSE}
  57.    db      66h
  58.    mov     ax, word ptr a   { mov  eax, a }
  59.    db      66h
  60.    mov     bx, word ptr b   { mov  ebx, b }
  61.    db      66h
  62.    mov     cx, word ptr c   { mov  ecx, c }
  63.    db      66h
  64.    imul    bx               { imul ebx    }
  65.    db      66h
  66.    idiv    cx               { idiv ecx    }
  67.    db      66h
  68.    db      0Fh
  69.    db      0A4h
  70.    db      0C2h
  71.    db      10h              { shld edx, eax, 16 }
  72. {$ENDIF}
  73. end;
  74. {************************************************************************}
  75. { function MulDiv32RN(a,b,c: Longint): Longint = (a * b + c/2) / c      *}
  76. {************************************************************************}
  77. function MulDiv32RN(a,b,c: Longint): Longint; assembler;
  78. asm
  79. {$IFDEF WIN32}
  80.    imul    edx
  81.    idiv    ecx
  82.    xchg    eax, edx
  83.    push    edx
  84.    shl     eax, 1
  85.    cdq
  86.    idiv    ecx
  87.    pop     ecx
  88.    add     eax, ecx
  89. {$ELSE}
  90.    db      66h
  91.    mov     ax, word ptr a   { mov  eax, a   }
  92.    db      66h
  93.    mov     dx, word ptr b   { mov  edx, b   }
  94.    db      66h
  95.    mov     cx, word ptr c   { mov  ecx, c   }
  96.    db      66h
  97.    imul    dx               { imul edx      }
  98.    db      66h
  99.    idiv    cx               { idiv ecx      }
  100.    db      66h
  101.    xchg    ax, dx           { xchg eax, edx }
  102.    db      66h
  103.    push    dx               { push edx      }
  104.    db      66h
  105.    shl     ax, 1            { shl eax, 1    }
  106.    db      66h
  107.    cwd                      { cdq           }
  108.    db      66h
  109.    idiv    cx               { idiv ecx      }
  110.    db      66h
  111.    pop     cx               { pop ecx       }
  112.    db      66h
  113.    add     ax, cx           { add eax, ecx  }
  114.    db      66h
  115.    db      0Fh
  116.    db      0A4h
  117.    db      0C2h
  118.    db      10h              { shld edx, eax, 16 }
  119. {$ENDIF}
  120. end;
  121. {************************************************************************}
  122. { function MulDivRD(a,b,c: Longint): Longint = (a * b) / c              *}
  123. {************************************************************************}
  124. function MulDivRD(a,b,c: Longint): Longint; assembler;
  125. asm
  126. {$IFDEF WIN32}
  127.    mul     edx
  128.    div     ecx
  129. {$ELSE}
  130.    db      66h
  131.    mov     ax, word ptr a  { mov  eax, a }
  132.    db      66h
  133.    mov     bx, word ptr b  { mov  ebx, b }
  134.    db      66h
  135.    mov     cx, word ptr c  { mov  ecx, c }
  136.    db      66h
  137.    mul     bx              { mul  ebx    }
  138.    db      66h
  139.    div     cx              { div  ecx    }
  140.    db      66h
  141.    db      00Fh
  142.    db      0A4h
  143.    db      0C2h
  144.    db      10h             { shld edx, eax, 16 }
  145. {$ENDIF}
  146. end;
  147. {************************************************************************}
  148. { function MulDivRN(a,b,c: Longint): Longint = (a * b + c/2) / c        *}
  149. {************************************************************************}
  150. function MulDivRN(a,b,c: Longint): Longint; assembler;
  151. asm
  152. {$IFDEF WIN32}
  153.    mul     edx
  154.    push    ecx
  155.    shr     ecx, 1
  156.    add     eax, ecx
  157.    adc     edx, 0
  158.    pop     ecx
  159.    div     ecx
  160. {$ELSE}
  161.    db      66h
  162.    mov     ax, word ptr a  { mov  eax, a  }
  163.    db      66h
  164.    mov     bx, word ptr b  { mov  ebx, b  }
  165.    db      66h
  166.    mov     cx, word ptr c  { mov  ecx, c  }
  167.    db      66h
  168.    mul     bx              { mul  ebx     }
  169.    db      66h
  170.    mov     bx, cx          { mov  ebx,ecx }
  171.    db      66h
  172.    sar     bx, 1           { sar  ebx,1   }
  173.    db      66h
  174.    add     ax, bx          { add  eax,ebx }
  175.    db      66h
  176.    adc     dx, 0           { adc  edx,0   }
  177.    db      66h
  178.    div     cx              { div  ecx     }
  179.    db      66h
  180.    db      0Fh
  181.    db      0A4h
  182.    db      0C2h
  183.    db      10h             { shld edx, eax, 16 }
  184. {$ENDIF}
  185. end;
  186. {************************************************************************}
  187. { function MulDivRU(a,b,c: Longint): Longint = (a * b + c-1) / c        *}
  188. {************************************************************************}
  189. function MulDivRU(a,b,c: Longint): Longint; assembler;
  190. asm
  191. {$IFDEF WIN32}
  192.    mul     edx
  193.    dec     ecx
  194.    add     eax, ecx
  195.    adc     edx, 0
  196.    inc     ecx
  197.    div     ecx
  198. {$ELSE}
  199.    db      66h
  200.    mov     ax, word ptr a   { mov  eax, a  }
  201.    db      66h
  202.    mov     bx, word ptr b   { mov  ebx, b  }
  203.    db      66h
  204.    mov     cx, word ptr c   { mov  ecx, c  }
  205.    db      66h
  206.    mul     bx               { mul  ebx     }
  207.    db      66h
  208.    mov     bx, cx           { mov  ebx,ecx }
  209.    db      66h
  210.    dec     bx               { dec  ebx     }
  211.    db      66h
  212.    add     ax, bx           { add  eax,ebx }
  213.    db      66h
  214.    adc     dx, 0            { adc  edx,0   }
  215.    db      66h
  216.    div     cx               { div  ecx     }
  217.    db      66h
  218.    db      0Fh
  219.    db      0A4h
  220.    db      0C2h
  221.    db      10h              { shld edx, eax, 16 }
  222. {$ENDIF}
  223. end;
  224. {************************************************************************}
  225. {= function DivMod32(a,b,c,d): c := (a / b)    d := (a mod b)           *)     =}
  226. {************************************************************************}
  227. function DivMod32(Dividend: Longint; Divisor: Word;
  228.                   Var _Div, _Mod: Word): Word; assembler;
  229. asm
  230. {$IFDEF WIN32}
  231.    push    ebx
  232.    mov     ebx, edx
  233.    mov     edx, eax
  234.    shr     edx, 16
  235.    div     bx
  236.    mov     ebx, _Mod
  237.    mov     [ecx], ax
  238.    mov     [ebx], dx
  239.    pop     ebx
  240. {$ELSE}
  241.    mov     ax, Dividend.Word[0]
  242.    mov     dx, Dividend.Word[2]
  243.    div     Divisor
  244.    les     di, _Div
  245.    mov     es:[di], ax
  246.    les     di, _Mod
  247.    mov     es:[di], dx
  248. {$ENDIF}
  249. end;
  250. function Sal(Value: Longint;Shift: Byte): Longint; assembler;
  251. asm
  252. {$IFDEF WIN32}
  253.    mov     cl, dl
  254.    sal     eax, cl
  255. {$ELSE}
  256.    db      66h
  257.    mov     ax, word ptr Value { mov  eax, a  }
  258.    mov     cl, Shift
  259.    db      66h
  260.    sal     ax, cl
  261.    db      66h
  262.    db      0Fh
  263.    db      0A4h
  264.    db      0C2h
  265.    db      10h                { shld edx, eax, 16 }
  266. {$ENDIF}
  267. end;
  268. function Sar(Value: Longint; Shift: Byte): Longint; assembler;
  269. asm
  270. {$IFDEF WIN32}
  271.    mov     cl, dl
  272.    sar     eax, cl
  273. {$ELSE}
  274.    db      66h
  275.    mov     ax, word ptr Value { mov  eax, a  }
  276.    mov     cl, Shift
  277.    db      66h
  278.    sar     ax, cl
  279.    db      66h
  280.    db      0Fh
  281.    db      0A4h
  282.    db      0C2h
  283.    db      10h                { shld edx, eax, 16 }
  284. {$ENDIF}
  285. end;
  286. { -------------------------------------------------------------------------- }
  287. { Result := (DstMax*(Val-SrcMin) + DstMin*(SrcMax-Val)) div (SrcMax-SrcMin); }
  288. { -------------------------------------------------------------------------- }
  289. function RangeScale(Val, SrcMin, SrcMax, DstMin, DstMax : Longint): Longint; assembler;
  290. asm
  291. {$IFDEF WIN32}
  292.    push    ebx
  293.    push    edi
  294.    mov     ebx, ecx
  295.    sub     ebx, edx           { ebx = SrcMax-SrcMin                }
  296.    sub     ecx, eax           { ecx = SrcMax-Val                   }
  297.    sub     eax, edx           { eax = Val-SrcMin                   }
  298.    imul    DstMax             { edx:eax = first product            }
  299.    xchg    eax, ecx           { ecx = low dword, eax = SrcMax-Val  }
  300.    mov     edi, edx           { save high dword                    }
  301.    imul    DstMin             { second multiplication              }
  302.    add     eax, ecx           { 64 bit addition                    }
  303.    adc     edx, edi
  304.    idiv    ebx                { div (SrcMax-SrcMin)                }
  305.    pop     edi
  306.    pop     ebx
  307. {$ELSE}
  308.    db      66h
  309.    mov     cx, word ptr SrcMax
  310.    db      66h
  311.    mov     bx, cx
  312.    db      66h
  313.    sub     bx, word ptr SrcMin  { ebx = SrcMax-SrcMin                }
  314.    db      66h
  315.    mov     ax, word ptr Val     { eax = Val                          }
  316.    db      66h
  317.    sub     cx, ax               { ecx = SrcMax-Val                   }
  318.    db      66h
  319.    sub     ax, word ptr SrcMin  { eax = Val-SrcMin                   }
  320.    db      66h
  321.    imul    word ptr DstMax      { edx:eax = first product            }
  322.    db      66h
  323.    xchg    ax, cx               { ecx = low dword, eax = SrcMax-Val  }
  324.    db      66h
  325.    mov     di, dx               { save high dword                    }
  326.    db      66h
  327.    imul    word ptr DstMin      { second multiplication              }
  328.    db      66h
  329.    add     ax, cx               { 64 bit addition                    }
  330.    db      66h
  331.    adc     dx, di
  332.    db      66h
  333.    idiv    bx                   { div (SrcMax-SrcMin)                }
  334.    db      66h
  335.    db      0Fh
  336.    db      0A4h
  337.    db      0C2h
  338.    db      10h                  { shld edx, eax, 16                  }
  339. {$ENDIF}
  340. end;
  341. { -------------------------------------------------------------------------- }
  342. { Result := (DstMax*(Val-SrcMin) + DstMin*(SrcMax-Val)) div (SrcMax-SrcMin); }
  343. { -------------------------------------------------------------------------- }
  344. function RangeScaleRN(Val, SrcMin, SrcMax, DstMin, DstMax: Longint): Longint;
  345. var
  346.    ValF: Double;
  347. begin
  348.    ValF := Val;
  349.    Result := Round((DstMax*(ValF-SrcMin) + DstMin*(SrcMax-ValF)) / (SrcMax-SrcMin));
  350. end;
  351. { -------------------------------------------------------------------------- }
  352. { Result := (DstMax*(Val-SrcMin) + DstMin*(SrcMax-Val)) div (SrcMax-SrcMin); }
  353. { -------------------------------------------------------------------------- }
  354. function RangeScaleF(Val, SrcMin, SrcMax, DstMin, DstMax: Double): Double;
  355. begin
  356.    Result := (DstMax*(Val-SrcMin) + DstMin*(SrcMax-Val)) / (SrcMax-SrcMin);
  357. end;
  358. {$IFDEF WIN32}
  359. { -------------------------------------------------------------------------- }
  360. function MulCompare(a,b,c,d: Longint): Boolean;
  361. var
  362.    R: Boolean;
  363. begin
  364.    asm
  365.       mov    eax, a
  366.       mov    edx, b
  367.       imul   edx
  368.       push   eax
  369.       push   edx
  370.       mov    eax, c
  371.       mov    edx, d
  372.       imul   edx
  373.       pop    ecx
  374.       xor    ecx, edx
  375.       jnz    @@exit
  376.       pop    ecx
  377.       xor    ecx, eax
  378.       jnz    @@exit
  379.       mov    R, True
  380.       jmp    @@exit2
  381.    @@exit:
  382.       mov    R, False
  383.    @@exit2:
  384.    end;
  385.    Result := R;
  386. end;
  387. {$ENDIF}
  388. {-------------------------------------------------------------------------- }
  389. function MulDiv64(a, b, c: int64): int64;
  390. {$IFDEF DELPHI4}
  391. var
  392.    temp: extended;
  393. begin
  394.    temp := a;
  395.    Result := Trunc((temp*b)/c);
  396. {$ELSE}
  397. begin
  398.    Result := (a*b)/c;
  399. {$ENDIF}
  400. end;
  401. end.