0

正の fixnum から符号位置に少しシフトする方法を探しています。基本的に、私が望むのは、オーバーフロー チェックなしで fixnum 左シフトを実行する予測可能な (未定義ではない) 方法です。

非効率的な実装は次のようになります。

(define shift-left
  (lambda (value shift)
    (let ([unsigned-to-signed
       (lambda (value width)
         (let* ([sign-mask (bitwise-arithmetic-shift-left
                1 (- width 1))]
            [sign (bitwise-and value sign-mask)])
           (bitwise-ior
        (bitwise-bit-field value 0 width)
        (- sign))))])
      (unsigned-to-signed
       (bitwise-arithmetic-shift-left value shift)
       (fixnum-width)))))

(shift-left 1 59) ⇒ 576460752303423488
(shift-left 1 60) ⇒ -1152921504606846976
(shift-left 1 61) ⇒ 0

理想的には、これは単一の CPU 命令にコンパイルされます (少なくとも定数シフトの場合。レジスタと同じ幅またはそれより広いシフトを処理する方法が CPU によって異なります)。

4

1 に答える 1

0

IN スキームでは、実装定義の機能を探さない限り機能しません。

スキームでは、算術型のタワーが標準化されているため、数値表現の内側を制御するのは非常に不便です。

何らかの実装の内部を理解している場合にのみ、何をしようとしているのか意味がありません。そうでない場合は、時間を無駄にします。

于 2020-11-21T00:52:08.820 に答える