我正在寻找一种方法,将一个正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在处理与寄存器一样宽或更宽的移位的方式上有所不同(。
IN方案,除非您寻找实现定义的特性,否则它不会起作用。
在scheme中,它对算术类型的塔进行了标准化,这使得控制数字表示的内侧非常不方便。
只有当您了解某些实现的内部结构时,您尝试做的事情才有意义,否则您将浪费时间。