bitwise.scm 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. ; R6RS bitwise operations
  2. ; Taken from the R6RS document.
  3. (define (bitwise-if ei1 ei2 ei3)
  4. (bitwise-ior (bitwise-and ei1 ei2)
  5. (bitwise-and (bitwise-not ei1) ei3)))
  6. (define bitwise-arithmetic-shift arithmetic-shift)
  7. (define bitwise-arithmetic-shift-left bitwise-arithmetic-shift)
  8. (define (bitwise-arithmetic-shift-right ei1 ei2)
  9. (bitwise-arithmetic-shift ei1 (- ei2)))
  10. (define bitwise-bit-count bit-count)
  11. (define (bitwise-bit-set? ei1 ei2)
  12. (not (zero?
  13. (bitwise-and
  14. (bitwise-arithmetic-shift-left 1 ei2)
  15. ei1))))
  16. (define (bitwise-bit-field ei1 ei2 ei3)
  17. (let ((mask
  18. (bitwise-not
  19. (bitwise-arithmetic-shift-left -1 ei3))))
  20. (bitwise-arithmetic-shift-right
  21. (bitwise-and ei1 mask)
  22. ei2)))
  23. (define (bitwise-copy-bit ei1 ei2 ei3)
  24. (bitwise-if (bitwise-arithmetic-shift-left 1 ei2)
  25. (bitwise-arithmetic-shift-left ei3 ei2)
  26. ei1))
  27. (define (bitwise-copy-bit-field ei1 ei2 ei3 ei4)
  28. (bitwise-if (bitwise-and (bitwise-arithmetic-shift-left -1 ei2)
  29. (bitwise-not
  30. (bitwise-arithmetic-shift-left -1 ei3)))
  31. (bitwise-arithmetic-shift-left ei4 ei2)
  32. ei1))
  33. (define (bitwise-rotate-bit-field ei1 ei2 ei3 ei4)
  34. (let* ((n ei1)
  35. (start ei2)
  36. (end ei3)
  37. (count ei4)
  38. (width (- end start)))
  39. (if (positive? width)
  40. (let* ((count (remainder count width))
  41. (field0
  42. (bitwise-bit-field n start end))
  43. (field1 (bitwise-arithmetic-shift-left
  44. field0 count))
  45. (field2 (bitwise-arithmetic-shift-right
  46. field0
  47. (- width count)))
  48. (field (bitwise-ior field1 field2)))
  49. (bitwise-copy-bit-field n start end field))
  50. n)))
  51. (define (bitwise-reverse-bit-field ei1 ei2 ei3)
  52. (letrec* ((reverse-bit-field-recur
  53. (lambda (n1 n2 len)
  54. (if (> len 0)
  55. (reverse-bit-field-recur
  56. (bitwise-arithmetic-shift-right n1 1)
  57. (bitwise-copy-bit (bitwise-arithmetic-shift-left n2 1) 0 n1)
  58. (- len 1))
  59. n2))))
  60. (let ((width (- ei3 ei2)))
  61. (if (positive? width)
  62. (let ((field (bitwise-bit-field ei1 ei2 ei3)))
  63. (bitwise-copy-bit-field
  64. ei1 ei2 ei3 (reverse-bit-field-recur field 0 width)))
  65. ei1))))
  66. (define (bitwise-length ei)
  67. (do ((result 0 (+ result 1))
  68. (bits (if (negative? ei)
  69. (bitwise-not ei)
  70. ei)
  71. (bitwise-arithmetic-shift bits -1)))
  72. ((zero? bits)
  73. result)))
  74. (define (bitwise-first-bit-set ei)
  75. (cond ((eq? ei 0) -1)
  76. ((eq? (remainder ei 2) 1) 0)
  77. ((eq? (remainder ei 2) 0)
  78. (let loop ((num ei)
  79. (count 0))
  80. (if (or (eq? num 1)
  81. (eq? (remainder num 2) 1))
  82. count
  83. (loop (bitwise-arithmetic-shift-right num 1) (+ count 1)))))))