Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;*****************************************************************************
  2. ;*
  3. ;*                            Open Watcom Project
  4. ;*
  5. ;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. ;*
  7. ;*  ========================================================================
  8. ;*
  9. ;*    This file contains Original Code and/or Modifications of Original
  10. ;*    Code as defined in and that are subject to the Sybase Open Watcom
  11. ;*    Public License version 1.0 (the 'License'). You may not use this file
  12. ;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. ;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. ;*    provided with the Original Code and Modifications, and is also
  15. ;*    available at www.sybase.com/developer/opensource.
  16. ;*
  17. ;*    The Original Code and all software distributed under the License are
  18. ;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. ;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. ;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. ;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. ;*    NON-INFRINGEMENT. Please see the License for the specific language
  23. ;*    governing rights and limitations under the License.
  24. ;*
  25. ;*  ========================================================================
  26. ;*
  27. ;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
  28. ;*               DESCRIBE IT HERE!
  29. ;*
  30. ;*****************************************************************************
  31.  
  32.  
  33. include mdef.inc
  34. include struct.inc
  35.  
  36.         modstart        i64tos
  37.  
  38. ;
  39. ;
  40. ;       int _CmpBigInt( int sigdigits, int near *bigint )
  41. ;                              EAX             EDX
  42. ;
  43.         xdefp   __CmpBigInt
  44.         xdefp   __Rnd2Int
  45.         xdefp   __Bin2String
  46.  
  47.         defpe   __CmpBigInt
  48.         push    EDI             ; save EDI
  49.         push    ECX             ; save ECX
  50.         call    getpow10        ; get address of Power of 10 table
  51.         inc     EAX             ; ++sigdigits
  52.         lea     EDI,[EDI+EAX*8] ; point to Pow10Table[sigdigits+1]
  53.         mov     ECX,[EDX]       ; get 64-bit integer
  54.         mov     EDX,4[EDX]      ; ...(high part)
  55.         sub     EAX,EAX         ; set adjustment to 0
  56.         _loop                   ; loop
  57.           cmp   EDX,cs:[EDI]    ; - check against 10**k
  58.           _if   e               ; - if high parts equal
  59.             cmp   ECX,cs:4[EDI] ; - - compare low part
  60.           _endif                ; - endif
  61.           _quif b               ; - quit if num < 10**k
  62.           add   EDI,8           ; - set pointer to 10**(k+1)
  63.           inc   EAX             ; - increment adjustment word
  64.         _endloop                ; endloop
  65.         sub     EDI,8           ; point at 10**(k-1)
  66.         _loop                   ; loop
  67.           cmp   EDX,cs:[EDI]    ; - check against 10**k
  68.           _if   e               ; - if high parts equal
  69.             cmp   ECX,cs:4[EDI] ; - - compare low part
  70.           _endif                ; - endif
  71.           _quif nb              ; - quit if num >= 10**(k-1)
  72.           sub   EDI,8           ; - set pointer to 10**(k-2)
  73.           dec   EAX             ; - increment adjustment word
  74.         _endloop                ; endloop
  75.         pop     ECX             ; restore ECX
  76.         pop     EDI             ; restore EDI
  77.         ret                     ; return to caller
  78.         endproc __CmpBigInt
  79.  
  80. ;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
  81. ;[]
  82. ;[] Rnd2int rounds the real pointed to by EAX to a 64 bit integer.
  83. ;[]
  84. ;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
  85. ;       void _Rnd2Int( double near *realnum, int near *bigint )
  86. ;                               EAX                 EDX
  87. ;
  88.         defpe   __Rnd2Int
  89.         push    EBX             ; save registers
  90.         push    ECX             ; save ECX
  91.         push    EDX             ; save EDX
  92.         push    EBP             ; save EBP
  93.         push    ESI             ; save ESI
  94.         push    EDX             ; save address of bigint array
  95.         mov     EBP,EAX         ; get address of realnum
  96.         mov     ECX,[EBP]       ; load the number
  97.         mov     EBX,4[EBP]      ; . . .
  98.         mov     EBP,EBX         ; save high word
  99.         and     EBP,0FFF00000h  ; isolate exponent in EBP
  100.         xor     EBX,EBP         ; isolate mantissa in EDX
  101.         xor     EBX,00100000h   ; turn on implied '1' bit in mantissa
  102.         shr     EBP,20          ; move exponent to bottom part of word
  103.         sub     EBP,0433h       ; calculate difference from 2**53
  104.         _if     ne              ; if not already the right size
  105.           _if   a               ; - if too big
  106.             _loop               ; - - loop
  107.               shl   ECX,1       ; - - - shift real left by one
  108.               rcl   EBX,1       ; - - - . . .
  109.               dec   EBP         ; - - - decrement count
  110.             _until e            ; - - until count = 0
  111.           _else                 ; - else
  112.             sub EAX,EAX         ; - - clear remainder
  113.             sub ESI,ESI         ; - - clear remainder bit bucket
  114.             _loop               ; - - loop
  115.               shr   EBX,1       ; - - - shift real right by one
  116.               rcr   ECX,1       ; - - - . . .
  117.               rcr   EAX,1       ; - - - save remainder
  118.               adc   ESI,ESI     ; - - - remember if any bits fell off end
  119.               inc   EBP         ; - - - increment count
  120.             _until e            ; - - until e
  121.             _guess rup          ; - - do we have to round up?
  122.               cmp   EAX,80000000h;- - - compare remainder with .5000000
  123.               _quif b,rup       ; - - - kick out if less than .5
  124.               _if   e           ; - - - magical stuff if looks like a .5
  125.                 or      ESI,ESI ; - - - any bits dropped off the bottom
  126.                 _if     e       ; - - - if not
  127.                   test  ECX,1   ; - - - - - is bottom digit even?
  128.                   _quif e,rup   ; - - - - - kick out if it is
  129.                 _endif          ; - - - - endif
  130.               _endif            ; - - - endif
  131.               add   ECX,01      ; - - - round up the number
  132.               adc   EBX,00      ; - - - . . .
  133.             _endguess           ; - - endguess
  134.           _endif                ; - endif
  135.         _endif                  ; endif
  136.         pop     EBP             ; get address of bigint array
  137.         mov     [EBP],ECX       ; store 64-bit integer
  138.         mov     4[EBP],EBX      ; . . .
  139.         pop     ESI             ; restore ESI
  140.         pop     EBP             ; restore EBP
  141.         pop     EDX             ; restore EDX
  142.         pop     ECX             ; restore ECX
  143.         pop     EBX             ; restore EBX
  144.         ret                     ; return
  145.         endproc __Rnd2Int
  146.  
  147. ;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
  148. ;[]
  149. ;[] Bin2string  converts a binary integer into a string
  150. ;[]
  151. ;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
  152. ;       void _Bin2String(
  153. ;               int near *bigint,       /* EAX */
  154. ;               char near *bufptr,      /* EDX */
  155. ;               int sigdigits )         /* EBX */
  156. ;
  157.         defpe   __Bin2String
  158.         push    EBP             ; save EBP
  159.         push    EDI             ; save EDI
  160.         push    ECX             ; save ECX
  161.         push    EBX             ; save EBX
  162.         mov     EBP,EAX         ; get address of bigint array
  163.         mov     ECX,[EBP]       ; get 64-bit integer
  164.         mov     EAX,4[EBP]      ; . . .
  165.         mov     EBP,EDX         ; get buffer pointer
  166.         add     EBP,EBX         ; point to end of buffer
  167.         mov     byte ptr [EBP],0; put in null character
  168. ;
  169. ; input:
  170. ;       EAX:ECX - 64-bit integer
  171. ;       EBP - pointer to buffer for digits
  172. ;       EBX - digit count
  173.  
  174.         push    EAX             ; save high word of quotient
  175.         _loop                   ; loop
  176.           pop   EAX             ; - restore high word of quotient
  177.           mov   EDI,10000       ; - divisor is 10000
  178.           sub   EDX,EDX         ; - zero high word
  179.           or    EAX,EAX         ; - check high word
  180.           jne   div1            ; - do all divides
  181.           or    ECX,ECX         ; - check low order word
  182.           jne   div2            ; - skip first divide
  183.           push  EAX             ; - save high word of quotient
  184.           jmp   short div5      ; - result is 0
  185. div1:     div   EDI             ; - divide EAX:ECX by 10000
  186. div2:     xchg  ECX,EAX         ; - ...
  187.           div   EDI             ; - ...
  188.  
  189. ;   quotient is in ECX:EAX
  190. ;   remainder is in EDX
  191.  
  192.           xchg  ECX,EAX         ; - move quotient to EAX:ECX
  193.           push  EAX             ; - save high word of quotient
  194.           mov   EAX,EDX         ; - get remainder
  195.           mov   DL,100          ; - get divisor
  196.           div   DL              ; - split remainder into 2 parts
  197.           mov   DL,AH           ; - save low order part
  198.           mov   AH,0            ; - zero
  199.           aam                   ; - split top part into 2 digits
  200.           xchg  EDX,EAX         ; - DH, DL gets top 2 digits, AX gets low part
  201.           mov   AH,0            ; - zero
  202.           aam                   ; - split low part into 2 digits
  203. div5:     add   AX,3030h        ; - make ASCII digits
  204.           add   DX,3030h        ; - ...
  205.           sub   EBP,4           ; - move back 4
  206.           mov   3[EBP],AL       ; - put low order digit in buffer
  207.           dec   EBX             ; - decrement digit count
  208.           _quif e               ; - quit if done
  209.           mov   2[EBP],AH       ; - ...
  210.           dec   EBX             ; - decrement digit count
  211.           _quif e               ; - quit if done
  212.           mov   1[EBP],DL       ; - ...
  213.           dec   EBX             ; - decrement digit count
  214.           _quif e               ; - quit if done
  215.           mov   [EBP],DH        ; - put high order digit in buffer
  216.           dec   EBX             ; - decrement digit count
  217.         _until  e               ; until done
  218.  
  219.         pop     EAX             ; remove high word of quotient
  220.         pop     EBX             ; restore EBX
  221.         pop     ECX             ; restore ECX
  222.         pop     EDI             ; restore EDI
  223.         pop     EBP             ; restore EBP
  224.         ret                     ; return
  225.         endproc __Bin2String
  226.  
  227. ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
  228. ;<>                                                                  <>
  229. ;<>     64-bit integer powers of 10 table                            <>
  230. ;<>                                                                  <>
  231. ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
  232. getpow10 proc   near            ; get address of powers of 10 table
  233.         call    pow10end        ; call around the table
  234. pow10table:                     ; powers of 10 table
  235.         dd      000000000h,000000000h ; 0
  236.         dd      000000000h,000000001h ; 10**00
  237.         dd      000000000h,00000000ah ; 10**01
  238.         dd      000000000h,000000064h ; 10**02
  239.         dd      000000000h,0000003e8h ; 10**03
  240.         dd      000000000h,000002710h ; 10**04
  241.         dd      000000000h,0000186a0h ; 10**05
  242.         dd      000000000h,0000f4240h ; 10**06
  243.         dd      000000000h,000989680h ; 10**07
  244.         dd      000000000h,005f5e100h ; 10**08
  245.         dd      000000000h,03b9aca00h ; 10**09
  246.         dd      000000002h,0540be400h ; 10**10
  247.         dd      000000017h,04876e800h ; 10**11
  248.         dd      0000000e8h,0d4a51000h ; 10**12
  249.         dd      000000918h,04e72a000h ; 10**13
  250.         dd      000005af3h,0107a4000h ; 10**14
  251.         dd      000038d7eh,0a4c68000h ; 10**15
  252.         dd      0002386f2h,06fc10000h ; 10**16
  253.         dd      001634578h,05d8a0000h ; 10**17
  254.         dd      00de0b6b3h,0a7640000h ; 10**18
  255.         dd      08ac72304h,089e80000h ; 10**19
  256.         dd      0ffffffffh,0ffffffffh ; MAX
  257.  
  258. pow10end proc   near
  259.         pop     EDI             ; get address of table
  260.         ret                     ; return
  261.         endproc pow10end
  262.         endproc getpow10
  263.  
  264.         endmod
  265.         end
  266.