130 lines
3.7 KiB
Racket
130 lines
3.7 KiB
Racket
#lang racket
|
|
|
|
(define (base-bytes v)
|
|
(define byte-count (cond [(zero? v) 0]
|
|
[else (define raw-bit-count (+ (integer-length v) 1))
|
|
(quotient (+ raw-bit-count 7) 8)]))
|
|
(for/list [(shift (in-range (* byte-count 8) 0 -8))]
|
|
(bitwise-bit-field v (- shift 8) shift)))
|
|
|
|
(define (mod n d) (modulo n d)) ;; sign equal to sign of d
|
|
(define (div n d) (/ (- n (mod n d)) d)) ;; sign equal to sign of n, or zero
|
|
|
|
;;---------------------------------------------------------------------------
|
|
;; One
|
|
;;
|
|
;; (define (intbytes* v)
|
|
;; (cond [(zero? v) '()]
|
|
;; [(= v -1) '()]
|
|
;; [else (append (intbytes* (div v 256)) (list (mod v 256)))]))
|
|
;;
|
|
;; (define (intbytes v)
|
|
;; (define bs (intbytes* v))
|
|
;; (define looks-negative (and (pair? bs) (>= (car bs) 128)))
|
|
;; (if (xor (negative? v) looks-negative)
|
|
;; (cons (if (negative? v) 255 0) bs)
|
|
;; bs))
|
|
|
|
;;---------------------------------------------------------------------------
|
|
;; Two
|
|
;;
|
|
;; (define (intbytes** v)
|
|
;; (cond [(zero? v) '()]
|
|
;; [else (append (intbytes** (quotient v 256)) (list (remainder v 256)))]))
|
|
;;
|
|
;; (define (intbytes* v)
|
|
;; (define bs (intbytes** v))
|
|
;; (if (and (pair? bs) (>= (car bs) 128))
|
|
;; (cons 0 bs)
|
|
;; bs))
|
|
;;
|
|
;; (define (intbytes v)
|
|
;; (if (negative? v)
|
|
;; (map (lambda (n) (- 255 n)) (intbytes* (- (+ v 1))))
|
|
;; (intbytes* v)))
|
|
|
|
;;---------------------------------------------------------------------------
|
|
;; Three
|
|
;;
|
|
;; (define (intbytes+ v)
|
|
;; (cond [(>= v 128) (append (intbytes+ (div v 256)) (list (mod v 256)))]
|
|
;; [else (list (mod v 256))]))
|
|
;;
|
|
;; (define (intbytes- v)
|
|
;; (cond [(< v -128) (append (intbytes- (div v 256)) (list (mod v 256)))]
|
|
;; [else (list (mod v 256))]))
|
|
;;
|
|
;; (define (intbytes v)
|
|
;; (cond [(negative? v) (intbytes- v)]
|
|
;; [(zero? v) '()]
|
|
;; [(positive? v) (intbytes+ v)]))
|
|
|
|
;;---------------------------------------------------------------------------
|
|
;; Four
|
|
;;
|
|
;; (define (intbytes* v)
|
|
;; (append (if (<= -128 v 127)
|
|
;; '()
|
|
;; (intbytes* (div v 256)))
|
|
;; (list (mod v 256))))
|
|
;;
|
|
;; (define (intbytes v)
|
|
;; (if (zero? v)
|
|
;; '()
|
|
;; (intbytes* v)))
|
|
|
|
;;---------------------------------------------------------------------------
|
|
;; Five
|
|
;;
|
|
;; (define (intbytes* v)
|
|
;; (if (<= -128 v 127)
|
|
;; (list (mod v 256))
|
|
;; (append (intbytes* (div v 256)) (list (mod v 256)))))
|
|
;;
|
|
;; (define (intbytes v)
|
|
;; (if (zero? v)
|
|
;; '()
|
|
;; (intbytes* v)))
|
|
|
|
;;---------------------------------------------------------------------------
|
|
;; Six
|
|
|
|
(define (intbytes* v)
|
|
(if (<= -128 v 127)
|
|
(list (bitwise-and v 255))
|
|
(append (intbytes* (arithmetic-shift v -8)) (list (bitwise-and v 255)))))
|
|
|
|
(define (intbytes v)
|
|
(if (zero? v)
|
|
'()
|
|
(intbytes* v)))
|
|
|
|
(define cases `(
|
|
(-257 (#xfe #xff))
|
|
(-256 (#xff #x00))
|
|
(-255 (#xff #x01))
|
|
(-129 (#xff #x7f))
|
|
(-128 (#x80))
|
|
(-127 (#x81))
|
|
(-2 (#xfe))
|
|
(-1 (#xff))
|
|
(0 ())
|
|
(1 (#x01))
|
|
(127 (#x7f))
|
|
(128 (#x00 #x80))
|
|
(255 (#x00 #xff))
|
|
(256 (#x01 #x00))
|
|
(32767 (#x7f #xff))
|
|
(32768 (#x00 #x80 #x00))
|
|
(65535 (#x00 #xff #xff))
|
|
(65536 (#x01 #x00 #x00))
|
|
))
|
|
|
|
(module+ test
|
|
(require rackunit)
|
|
(for [(c (in-list cases))]
|
|
(match-define (list input output) c)
|
|
(writeln (list input output (base-bytes input) (intbytes input)))
|
|
(check-equal? output (base-bytes input))
|
|
(check-equal? output (intbytes input))))
|