javascript - 在 Clojure 中实现 JavaScript 的左移运算符

标签 javascript clojure bit-manipulation

我需要执行一个左移操作,其行为方式与 JavaScript 的完全相同。问题是这样的:

a << 16

仅当 a <= 32767 时才表现得像 Clojure 的“bit-shift-left”:

// JS
32767 << 16 // 2147418112
32768 << 16 // -2147483648
567890 << 16 // -1437466624

;; CLJ
(bit-shift-left 32767 16) // 2147418112
(bit-shift-left 32768 16) // 2147483648
(bit-shift-left 567890 16) // 37217239040

我注意到,当执行“37431 << 16”时,JS 在二进制级别上执行的操作与 Clojure 完全不同。 Clojure 将 1001001000110111 转换为 10010010001101110000000000000000,而 JS 将 1001001000110111 转换为 1101101110010010000000000000000:

// CLJ, then JS
10 01001 00011 01110 00000 00000 00000
 1 10110 11100 10010 00000 00000 00000

我注意到这是二进制补码,并且我注意到 JS 可能会这样做,因为它不能(出于某种原因)为此使用超过 32 位(所有位级操作都在 32 位上完成,也许?),所以我想知道如果数字高于 32767,我是否应该对数字应用二进制补码。但话又说回来,我是 Clojure 新手,所以我不太确定如何执行此操作。

最佳答案

首先, clojure.core/bit-shift-left 会将其左侧输入视为 long 。您可以使用 clojure.lang.Numbers/shiftLeftInt 将数字转换为 int :

(clojure.lang.Numbers/shiftLeftInt 567890 16)
;= -1437466624

这与您在 JavaScript 中获得的结果匹配。 clojure.core 中没有围绕此静态方法的包装器,但您可以提供自己的包装器。

其次, (clojure.lang.Numbers/shiftLeftInt 37431 16) 在 Clojure (1.8.0) 中计算为 -1841889280 ,而 37431 << 16 在 Node (4.4.5) 中计算为相同的数字 -1841889280 ,所以我认为那里没有任何问题。不过,您必须在 JavaScript 中将 >>> 0 应用于您的数字,才能获得字符串表示形式中的预期位:

// Node 4.4.5
> ((37431 << 16) >>> 0).toString(2)
'10010010001101110000000000000000'

值得注意的是,在没有 &“无符号转换”的情况下,使用 >>> 0 找出各个位也可以正常工作:

> (37431 << 16) & (1 << 31)
-2147483648
> (37431 << 16) & (1 << 30)
0
> (37431 << 16) & (1 << 29)
0
> (37431 << 16) & (1 << 28)
268435456

您可以在 Clojure 中计算这两种字符串表示形式:

(Integer/toString (clojure.lang.Numbers/shiftLeftInt 37431 16) 2)
;= "-1101101110010010000000000000000"
(Integer/toBinaryString (clojure.lang.Numbers/shiftLeftInt 37431 16))
;= "10010010001101110000000000000000"

请注意,在 Java 中,移位运算符仅考虑右操作数的最右边 5 或 6 位(分别用于 intlong ),因此,如果您尝试将 intlong 移位超过 31/63位,您将不会得到您期望的结果。 java.lang.BigInteger 有一个 shiftLeft 方法没有此限制。

关于javascript - 在 Clojure 中实现 JavaScript 的左移运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38381719/

相关文章:

javascript - SAPUI5:自定义控件未加载到表 groupHeaderFactory 中

JavaScript 在 Chrome 中工作,在 Firefox 中不工作

clojure - leiningen 默认存储库是什么?

javascript - SHA-3 的所有舍入常数究竟是如何生成的?

c - 优化位运算

javascript - 本地范围对象有时在带有 .then 的 JavaScript Promise 中工作

programming-languages - 哪些因素可以决定 Clojure、Scala 或 Haskell 是否会获得关注?

clojure - 为什么 clojure.core 中的某些 Clojure 函数没有记录在案?

c - 在C语言中我如何 “reverse”这个运算符| =

javascript - 使用 Math.max() 计算最大日期 JavaScript 日期对象文档