2016-06-30 6 views
2

Schema haben nur >> und << Funktionen. Wie kann ich javascript >>> in Schema tun?Wie führt man JavaScript >>> in Schema?

Ich brauche diese Funktion in Schema schreiben:

function bit_rol (num, cnt) { 
    return (num << cnt) | (num >>> (32 - cnt)) 
} 

das wird nicht funktionieren, weil >>> ungebundenen Symbol:

(define (bit-rol num cnt) 
    (| (<< num cnt) (>>> num (- 32 cnt)))) 

Antwort

2

Hier ist eine Lösung:

(define (complement x) 
    (if (negative? x) 
     (- (expt 2 32) (- x)) 
     x)) 

(define (>>> x n) 
    (cond 
    [(>= n 0) (cond 
       [(= x 0) 0] 
       [(> x 0) (quotient x (expt 2 n))] 
       [(< x 0) (>>> (complement x) n)] 
       [else (error '>>> "strange number detected")])] 
    [else (error '>>> "expected a non-negative shift")])) 

(>>> 5 2) ; 1 
(>>> -5 2) ; 1073741822 
2

Da Sie keine Version angegeben haben, erwarte ich, dass Sie die neueste Vollversion verwenden, nämlich R6RS. R6RS hat eine genaue bitweise artithmetic Bibliothek (rnrs arithmetic bitwise (6))

Schema nicht >> hat, da er die Zahlen nicht durch eine feste Breite gebunden sind, aber >>> und << mit bitwise-arithmetic-shift mit eiher negativer oder positiver Anzahl von Verschiebungen implementiert. Es gibt auch spezifische rechte und linke Versionen, die jedoch redundant sind.

Scheme hat bitwise-rotate-bit-field und ich glaube, Sie emulieren es in Ihrem JavaScript, da es keine rotierende Anweisung bietet. Ihre bit-rol kann mit nur einem Einsatz dieser implementiert werden:

(import (rnrs) 
     (rnrs arithmetic bitwise (6))) 

(define (make-bit-rot bit-width) 
    (lambda (n step)  
    (bitwise-rotate-bit-field n 
           0 
           bit-width 
           (if (negative? step) 
            (mod step bit-width) 
            step)))) 

(define rot-4 (make-bit-rot 4)) 
(rot-4 #b0001 -1) ; ==> #b1000 
(rot-4 #b1000 1) ; ==> #b0001 
(rot-4 #b1000 3) ; ==> #b0100 


// Seeems you are interested in 32 bit rotate 
(define rot-32 (make-bit-rot 32)) 
+0

Ich möchte diese Funktion tragbar sein, damit ich brauche es für R5RS. – jcubic

+1

@jcubic It ** ist ** portabel für alle Implementierungen, die R6RS unterstützen. Wenn Sie die Version von Scheme kennen, können Sie sie markieren. r7rs, r6rs und r5rs sind Tags in SO, mit denen Sie eine Standardversion angeben können. Ich werde nur die Antwort verlassen, da es einige r6rs Benutzer sein werden, die diese Antwort nützlich finden. – Sylwester