home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1989 / 05 / struct.asc < prev    next >
Text File  |  1989-05-12  |  14KB  |  456 lines

  1. _Language-Independent Dynamic Pseudostructures_
  2. by Bruce Tonkin
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. DEFDBL A-Z
  8. DIM i AS LONG
  9. k = 1# / LOG(2#)   'convert to base 2
  10. OPEN "o", 1, "c:temp"
  11. FOR i = 1 TO 100000
  12.     t = t + LOG(i) * k
  13.     IF i MOD 10000 = 0 OR i < 11 OR i = 100 OR 
  14.     (i < 10000 AND i MOD 1000 = 0) THEN 
  15.     PRINT #1, i, t / i, (LOG(i * .737) * k) - 1
  16. NEXT i
  17.  
  18.  
  19. [LISTING TWO]
  20.  
  21. .MODEL MEDIUM
  22. .CODE
  23. PUBLIC convint
  24. ;convint written by Bruce W. Tonkin on 8-14-88 for use with QB 4.0 & MASM 5.0
  25. ;convint will convert a binary 2-byte integer passed as a string into
  26. ;a string with the bytes re-ordered so an ASCII-order sort will sort in 
  27. ;numeric order.  It is called with:
  28. ;call convint (x$)
  29. ;where x$ is the string to convint (in the current data segment).
  30. ;The routine does not check for a zero length of the passed string.
  31. convint PROC
  32.     push bp        ;save old BP
  33.     mov  bp,sp     ;Set framepointer to old stack
  34.     mov  bx,[bp+6] ;bx points to string length, which we don't need
  35.     mov  bx,[bx]+2 ;move the string address to bx
  36.     mov  dh,byte ptr [bx]    ;get first byte
  37.     inc  bx                  ;point to next byte
  38.     mov  dl,byte ptr [bx]    ;get second byte
  39.     xor  dl,080h             ;invert the sign bit
  40.     mov  byte ptr [bx],dh    ;store first byte where second was
  41.     dec  bx                  ;now for modified second byte
  42.     mov  byte ptr [bx],dl    ;store where first byte went
  43.     pop  bp        ;restore old base pointer
  44.     ret  2         ;clear 2 bytes of parameters on return
  45. convint ENDP
  46.     END
  47.  
  48.  
  49. [LISTING THREE]
  50.  
  51. .MODEL MEDIUM
  52. .CODE
  53. PUBLIC convlong
  54. ;convlong written by Bruce W. Tonkin on 8-14-88 for use with QB 4.0 & MASM 5.0
  55. ;convlong will convert a long integer passed as a packed 4-byte string into
  56. ;a string with the bytes re-ordered so an ASCII-order sort will sort in 
  57. ;numeric order.  It is called with:
  58. ;call convlong (x$)
  59. ;where x$ is the string to convlong (in the current data segment).
  60. ;The routine does not check for a zero length of the passed string.
  61. convlong PROC
  62.     push bp        ;save old BP
  63.     mov  bp,sp     ;Set framepointer to old stack
  64.     mov  bx,[bp+6] ;address of string length isn't needed
  65.     mov  bx,[bx]+2 ;move the string address to bx
  66.     mov  dh,byte ptr [bx]    ;get first byte
  67.     inc  bx                  ;point to next byte
  68.     mov  dl,byte ptr [bx]    ;get second byte
  69.     inc  bx                  ;point to third byte
  70.     mov  ah,byte ptr [bx]    ;get third byte
  71.     inc  bx                  ;point to last byte
  72.     mov  al,byte ptr [bx]    ;get fourth and last byte
  73.     mov  byte ptr [bx],dh    ;store first byte in fourth spot
  74.     dec  bx                  ;point to third spot
  75.     mov  byte ptr [bx],dl    ;store former second byte
  76.     dec  bx                  ;point to second spot
  77.     mov  byte ptr [bx],ah    ;store former third byte
  78.     dec  bx                  ;point to former first byte spot
  79.     xor  al,080h             ;invert the sign bit
  80.     mov  byte ptr [bx],al    ;and store the fourth byte where first was
  81.     pop  bp        ;restore old base pointer
  82.     ret  2         ;clear 2 bytes of parameters on return
  83. convlong ENDP
  84.     END
  85.  
  86.  
  87. [LISTING FOUR]
  88.  
  89.  
  90. .MODEL MEDIUM
  91. .CODE
  92. PUBLIC convof
  93. ;convof written by Bruce W. Tonkin on 8-14-88 for use with QB 4.0 & MASM 5.0
  94. ;convof will convert a Microsoft Binary format floating-point number passed as
  95. ;a string into a string with the bytes re-ordered so an ASCII-order sort will
  96. ;sort in numeric order.  It is called with:
  97. ;call convof (x$)
  98. ;where x$ is the string to convof (in the current data segment).
  99. ;The routine does not check for a zero length of the passed string.
  100. convof PROC
  101.     push bp        ;save old BP
  102.     mov  bp,sp     ;Set framepointer to old stack
  103.     mov  bx,[bp+6] ;move the string length to cx
  104.     mov  cx,[bx]
  105.     push si        ;save si--used by routine
  106.     mov  ax,cx     ;copy cx into ax
  107.     dec  ax        ;subtract one from ax
  108.     shr  cx,1      ;divide cx by two
  109.     mov  bx,[bx]+2 ;move the string address to bx
  110.     push bx        ;save that address
  111.     add  bx,ax     ;look at the end of the string
  112.     cmp byte ptr [bx],0 ;check the first byte
  113.     pop  bx        ;restore string pointer
  114.     jnz  va        ;last byte was not zero
  115.     mov  byte ptr [bx],081h  ;it was zero, so make first byte 129
  116.     dec  cx        ;and make all other bytes zero
  117.     inc  bx        ;point to next byte
  118. vt: mov  byte ptr [bx],0     ;clear it
  119.     inc  bx        ;point to next byte
  120.     loop vt        ;decrement cx and loop until done
  121.     jmp  vi        ;then go to the end and restore registers
  122. va: mov  si,bx     ;set up si to point to bytes to swap
  123.     add  si,ax     ;points to last byte of string
  124. iv: mov  dl,[bx]   ;first byte of string to dl
  125.     mov  dh,[si]   ;second byte to dh
  126.     mov  [bx],dh   ;and save it
  127.     mov  [si],dl   ;swap two bytes to reverse order
  128.     inc  bx        ;point to next byte
  129.     dec  si        ;and get ready for corresponding byte to move
  130.     loop iv        ;dec cx and repeat until all bytes were swapped
  131.     mov  bx,[bp+6] ;restore the original string pointer
  132.     mov  cx,[bx]   ;length to cx
  133.     mov  bx,[bx]+2 ;location in bx
  134. ;at this point, all the bytes in the string have been put in reverse order
  135.     mov  ah,[bx]   ;save first string byte into ah
  136.     inc  bx        ;point to second byte
  137.     mov  al,[bx]   ;second byte into al
  138.     dec  bx        ;now point to first byte again
  139.     mov  dh,ah     ;save copies
  140.     mov  dl,al     ;of both bytes
  141.     push cx        ;save cx=length
  142.     mov  cl,7      ;get ready to rotate
  143.     shl  ah,cl     ;move low bit left 7 positions for first byte
  144.     shr  al,cl     ;move high bit right 7 positions for second byte
  145.     pop  cx        ;restore count in cx
  146.     and  dl,07fh   ;mask high bit for byte two
  147.     add  dl,ah     ;low bit of byte one to high bit of byte two
  148.     shr  dh,1      ;shift byte one right one bit
  149.     or   dh,080h   ;and turn high bit on for byte one
  150.     cmp  al,1      ;check status of former high bit on byte two
  151.     jnz  v         ;high bit wasn't set
  152.     push bx        ;save string pointer
  153.     xor  dx,0ffffh ;invert first two bytes
  154.     inc  bx        ;point to second byte
  155.     inc  bx        ;point to third byte
  156.     dec  cx        ;decrement counter accordingly
  157.     dec  cx
  158. vv: xor  byte ptr [bx],0ffh  ;invert successive bytes three to end
  159.     inc  bx        ;point to next byte
  160.     loop vv        ;decrement cx and repeat until done
  161.     pop  bx        ;restore string pointer
  162. v:  mov  byte ptr [bx],dh    ;save altered byte one
  163.     inc  bx
  164.     mov  byte ptr [bx],dl    ;and byte two
  165. vi: pop  si        ;restore si
  166.     pop  bp        ;restore old base pointer
  167.     ret  2         ;clear 2 bytes of parameters on return
  168. convof ENDP
  169.     END
  170.  
  171.  
  172. [LISTING FIVE]
  173.  
  174.  
  175.  
  176. .MODEL MEDIUM
  177. .CODE
  178. PUBLIC convnf
  179. ;convnf written by Bruce W. Tonkin on 8-13-88 for use with QB 4.0 & MASM 5.0
  180. ;convnf will convert an IEEE floating-point number passed as a string into
  181. ;a string with the bytes re-ordered so an ASCII-order sort will sort in 
  182. ;numeric order.  It is called with:
  183. ;call convnf (x$)
  184. ;where x$ is the string to convnf (in the current data segment).
  185. ;The routine does not check for a zero length of the passed string.
  186. convnf PROC
  187.     push bp        ;save old BP
  188.     mov  bp,sp     ;Set framepointer to old stack
  189.     mov  bx,[bp+6] ;move the string length to cx
  190.     mov  cx,[bx]
  191.     push si        ;save si--used by routine
  192.     mov  ax,cx     ;copy cx into ax
  193.     dec  ax        ;subtract one from ax
  194.     shr  cx,1      ;divide cx by two
  195.     mov  bx,[bx]+2 ;move the string address to bx
  196.     mov  si,bx     ;set up si to point to bytes to swap
  197.     add  si,ax     ;points to last byte of string
  198. iv: mov  dl,[bx]   ;first byte of string to dl
  199.     mov  dh,[si]   ;second byte to dh
  200.     mov  [bx],dh   ;and save it
  201.     mov  [si],dl   ;swap two bytes to reverse order
  202.     inc  bx        ;point to next byte
  203.     dec  si        ;and get ready for corresponding byte to move
  204.     loop iv        ;dec cx and repeat until all bytes were swapped
  205.     mov  bx,[bp+6] ;restore the original string pointer
  206.     mov  cx,[bx]   ;length to cx
  207.     mov  bx,[bx]+2 ;location in bx
  208.     test byte ptr [bx],080h ;check the high-order bit of the first byte
  209.     jnz  v         ;high-order bit was set
  210.     xor  byte ptr [bx],080h    ;fix the first byte
  211.     jmp  vi        ;and done
  212. v:  xor  byte ptr [bx],0ffh    ;invert all the bytes in the string
  213.     inc  bx        ;next location
  214.     loop v         ;dec cx and repeat until all bytes have been inverted
  215. vi: pop  si        ;restore si
  216.     pop  bp        ;restore old base pointer
  217.     ret  2         ;clear 2 bytes of parameters on return
  218. convnf ENDP
  219.     END
  220.  
  221.  
  222.  
  223. [LISTING SIX]
  224.  
  225.  
  226. .MODEL MEDIUM
  227. .CODE
  228. PUBLIC INVERT
  229. ;INVERT written by Bruce W. Tonkin on 8-13-88 for use with QB 4.0 & MASM 5.0
  230. ;INVERT will xor all the bytes in a string, thus allowing it to be sorted in
  231. ;descending order.  It is called with:
  232. ;call INVERT (x$)
  233. ;where x$ is the string to invert (in the current data segment).
  234. ;The routine does not check for a zero length of the passed string.
  235. INVERT PROC
  236.     push bp        ;save old BP
  237.     mov  bp,sp     ;Set framepointer to old stack
  238.     mov  bx,[bp+6] ;move the string length to cx
  239.     mov  cx,[bx]
  240.     mov  bx,[bx]+2 ;put the string address into bx
  241. iv: xor  byte ptr [bx],0ffh  ;convert the first byte
  242.     inc  bx
  243.     loop iv        ;decrement cx and repeat until done
  244.     pop  bp        ;restore old base pointer
  245.     ret  2         ;clear 2 bytes of parameters on return
  246. INVERT ENDP
  247.     END
  248.  
  249.  
  250. [LISTING SEVEN]
  251.  
  252.  
  253. defint a-z
  254. dim t!(17)
  255. dim t$(17)
  256. open"o",1,"bench.dat"
  257. cls
  258. t!(0)=timer
  259. for i=1 to 100
  260.     for j=1 to 1000
  261.     next j
  262. next i
  263. t!(0)=timer-t!(0)  'time for bare loop
  264. t$(0)="Raw integer loop"
  265.  
  266. d$=mki$(-13)
  267. t!(1)=timer
  268. for i=1 to 100
  269.     for j=1 to 1000
  270.          CALL convint(d$)
  271.     next j
  272. next i
  273. t!(1)=timer-t!(1)      'time for integer conversions
  274. t$(1)="Integer conversion"
  275.  
  276. d$=mkl$(-130000)
  277. t!(2)=timer
  278. for i=1 to 100
  279.     for j=1 to 1000
  280.          CALL convlong(d$)
  281.     next j
  282. next i
  283. t!(2)=timer-t!(2)      'time for long integer conversions
  284. t$(2)="Long integer conversion"
  285.  
  286. d$=string$(4,204)
  287. t!(3)=timer
  288. for i=1 to 100
  289.     for j=1 to 1000
  290.          CALL convof(d$)
  291.     next j
  292. next i
  293. t!(3)=timer-t!(3)      'time for old single-precision float conversion
  294. t$(3)="Old single float conversion"
  295.  
  296. d$=string$(8,204)
  297. t!(4)=timer
  298. for i=1 to 100
  299.     for j=1 to 1000
  300.          CALL convof(d$)
  301.     next j
  302. next i
  303. t!(4)=timer-t!(4)      'time for old double-precision float conversion
  304. t$(4)="Old double float conversion"
  305.  
  306. d$=mks$(-13.0405)
  307. t!(5)=timer
  308. for i=1 to 100
  309.     for j=1 to 1000
  310.          CALL convnf(d$)
  311.     next j
  312. next i
  313. t!(5)=timer-t!(5)      'time for IEEE single-precision float conversion
  314. t$(5)="IEEE single float conversion"
  315.  
  316. d$=mkd$(-13.04050607)
  317. t!(6)=timer
  318. for i=1 to 100
  319.     for j=1 to 1000
  320.          CALL convnf(d$)
  321.     next j
  322. next i
  323. t!(6)=timer-t!(6)      'time for IEEE double-precision float conversion
  324. t$(6)="IEEE double float conversion"
  325.  
  326. t!(7)=timer
  327. for i=1 to 100
  328.     for j=1 to 1000
  329.          CALL invert(d$)
  330.     next j
  331. next i
  332. t!(7)=timer-t!(7)      'time for inverting 8 bytes
  333. t$(7)="Invert 8 bytes"
  334.  
  335. a$="AB"
  336. b$="AX"
  337. t!(8)=timer
  338. for i=1 to 100
  339.     for j=1 to 1000
  340.          if a$>b$ then j=j+1
  341.     next j
  342. next i
  343. t!(8)=timer-t!(8)      'time to compare two-byte strings
  344. t$(8)="Compare two-byte strings"
  345.  
  346. a=100
  347. b=200
  348. t!(9)=timer
  349. for i=1 to 100
  350.     for j=1 to 1000
  351.          if a>b then j=j+1
  352.     next j
  353. next i
  354. t!(9)=timer-t!(9)      'time to compare two integers
  355. t$(9)="Compare two integers"
  356.  
  357. a$="ABCD"
  358. b$="ABCX"
  359. t!(10)=timer
  360. for i=1 to 100
  361.     for j=1 to 1000
  362.          if a$>b$ then j=j+1
  363.     next j
  364. next i
  365. t!(10)=timer-t!(10)    'time to compare two 4-byte strings
  366. t$(10)="Compare two four-byte strings"
  367.  
  368. a!=100.01!
  369. b!=200.01!
  370. t!(11)=timer
  371. for i=1 to 100
  372.     for j=1 to 1000
  373.          if a!>b! then j=j+1
  374.     next j
  375. next i
  376. t!(11)=timer-t!(11)    'time to compare two single floats
  377. t$(11)="Compare two single floats"
  378.  
  379. a#=100.01#
  380. b#=200.01#
  381. t!(12)=timer
  382. for i=1 to 100
  383.     for j=1 to 1000
  384.          if a#>b# then j=j+1
  385.     next j
  386. next i
  387. t!(12)=timer-t!(12)    'time to compare two double floats
  388. t$(12)="Compare two double floats"
  389.  
  390. a$="ABCDEFGH"
  391. b$="ABCDEFGX"
  392. t!(13)=timer
  393. for i=1 to 100
  394.     for j=1 to 1000
  395.          if a$>b$ then j=j+1
  396.     next j
  397. next i
  398. t!(13)=timer-t!(13)    'time to compare two 8-byte strings
  399. t$(13)="Compare two 8-byte strings"
  400.  
  401. a&=123456&
  402. b&=123457&
  403. t!(14)=timer
  404. for i=1 to 100
  405.     for j=1 to 1000
  406.          if a&>b& then j=j+1
  407.     next j
  408. next i
  409. t!(14)=timer-t!(14)    'time to compare two long integers
  410. t$(14)="Compare two long integers"
  411.  
  412. a$="ABCDEFGHIJKLMNOPQRST"
  413. b$="ABCDEFGHIJKLMNOPQRSX"
  414. t!(15)=timer
  415. for i=1 to 100
  416.     for j=1 to 1000
  417.          if a$>b$ then j=j+1
  418.     next j
  419. next i
  420. t!(15)=timer-t!(15)    'time to compare two 20-byte strings
  421. t$(15)="Compare two 20-byte strings"
  422.  
  423. a$="ABCDEFGHIJKLMNOPQRST"
  424. b$="XBCDEFGHIJKLMNOPQRST"
  425. t!(16)=timer
  426. for i=1 to 100
  427.     for j=1 to 1000
  428.          if a$>b$ then j=j+1
  429.     next j
  430. next i
  431. t!(16)=timer-t!(16)    'best? time to compare two 20-byte strings
  432. t$(16)="Compare two 20-byte strings (best?)"
  433.  
  434. t!(17)=timer
  435. for i=1 to 100
  436.     for j=1 to 1000
  437.          call dummy(a,b,c)
  438.     next j
  439. next i
  440. t!(17)=timer-t!(17)     'time to make a call with three parameters
  441. t$(17)="Three-integer-parameter call"
  442.  
  443. print t$(0),t!(0)
  444. print #1,t$(0),t!(0)
  445. for i=1 to 17
  446.     t!(i)=t!(i)-t!(0)
  447.     print t$(i),t!(i)
  448.     print #1,t$(i),t!(i)
  449. next i
  450.  
  451. sub dummy(a,b,c) static
  452.     c=1
  453. end sub
  454.  
  455.  
  456.