gpt4 book ai didi

javascript - 如何从八 (8) 个 4 位整数创建 32 位整数?

转载 作者:可可西里 更新时间:2023-11-01 01:51:50 27 4
gpt4 key购买 nike

假设我有一个最大 32 位整数 -

const a =
((2 ** 32) - 1)

const b =
parseInt("11111111111111111111111111111111", 2) // 32 bits, each is a one!

console.log(a === b) // true

console.log(a.toString(2))
// 11111111111111111111111111111111 (32 ones)

console.log(b.toString(2))
// 11111111111111111111111111111111 (32 ones)

到目前为止一切顺利。但现在假设我想使用八 (8) 个 4 位数字生成一个 32 位数字。这个想法很简单:将每个 4 位序列移位 (<<) 到位并将它们相加 (+) -

const make = ([ bit, ...more ], e = 0) =>
bit === undefined
? 0
: (bit << e) + make (more, e + 4)

const print = n =>
console.log(n.toString(2))

// 4 bits
print(make([ 15 ])) // 1111

// 8 bits
print(make([ 15, 15 ])) // 11111111

// 12 bits
print(make([ 15, 15, 15 ])) // 111111111111

// 16 bits
print(make([ 15, 15, 15, 15 ])) // 1111111111111111

// 20 bits
print(make([ 15, 15, 15, 15, 15 ])) // 11111111111111111111

// 24 bits
print(make([ 15, 15, 15, 15, 15, 15 ])) // 111111111111111111111111

// 28 bits
print(make([ 15, 15, 15, 15, 15, 15, 15 ])) // 1111111111111111111111111111

// almost there ... now 32 bits
print(make([ 15, 15, 15, 15, 15, 15, 15, 15 ])) // -1 :(

我得到 -1预期的结果是全 32 位,或 11111111111111111111111111111111 .

更糟糕的是,如果我从预期的结果开始并向后工作,我会得到预期的结果 -

const c =
`11111111111111111111111111111111`

const d =
parseInt(c, 2)

console.log(d) // 4294967295

console.log(d.toString(2) === c) // true

我尝试调试我的 make 函数以确保没有明显的问题 -

const make = ([ bit, ...more ], e = 0) =>
bit === undefined
? `0`
: `(${bit} << ${e}) + ` + make (more, e + 4)

console.log(make([ 15, 15, 15, 15, 15, 15, 15, 15 ]))
// (15 << 0) + (15 << 4) + (15 << 8) + (15 << 12) + (15 << 16) + (15 << 20) + (15 << 24) + (15 << 28) + 0

这个公式看起来是正确的。我想这可能与 + 有关并切换到按位或(|),这应该在这里有效地做同样的事情 -

const a =
parseInt("1111",2)

const b =
(a << 0) | (a << 4)

console.log(b.toString(2)) // 11111111

const c =
b | (a << 8)

console.log(c.toString(2)) // 111111111111

但是,我的 make 也遇到了同样的错误尝试组合所有八 (8) 个数字时的功能 -

const make = ([ bit, ...more ], e = 0) =>
bit === undefined
? 0
: (bit << e) | make (more, e + 4)

const print = n =>
console.log(n.toString(2))


print(make([ 15, 15, 15, 15, 15, 15, 15 ])) // 1111111111111111111111111111 (28 bits)

print(make([ 15, 15, 15, 15, 15, 15, 15, 15 ])) // -1 :(

什么给了?

目标是使用 JavaScript 将八 (8) 个 4 位整数转换为单个 32 位整数 - 这只是我的尝试。我很好奇我的功能哪里出了问题,但我愿意接受其他解决方案。

我想避免将每个 4 位整数转换为二进制字符串,将二进制字符串混合在一起,然后将二进制字符串解析为单个 int。首选数值解决方案。

最佳答案

按位运算符将产生一个有符号 32 位数字,这意味着如果位置 31 的位(从右边的最低有效位开始计算,即位 0)为 1,则number 将为负数。

为避免这种情况发生,请使用 << 以外的其他运算符或 | ,这两者都会产生一个带符号的 32 位数字。例如:

(bit * 2**e) + make (more, e + 4)

强制无符号 32 位

位移运算符旨在将结果强制到带符号的 32 位范围内,至少在 mdn 上是这样声明的。 (在撰写本文时):

The operands of all bitwise operators are converted to signed 32-bit integers

事实上这并不完全正确。 >>>运算符是一个异常(exception)。 EcmaScript 2015, section 12.5.8.1声明操作数在移入 0 位之前映射到 unsigned 32 位。因此,即使您移动 位,您也会看到这种效果。

您只需将它应用于最终值一次,例如在您的 print 中功能:

console.log((n>>>0).toString(2))

BigInt 解决方案

如果您需要超过 32 位,并且您的 JavaScript 引擎支持 BigInt喜欢some已经这样做了,然后将 BigInts 用于按位运算符中涉及的操作数——这些将使用 32 位有符号数字包装(注意 n 后缀):

const make = ([ bit, ...more ], e = 0n) =>
bit === undefined
? 0n
: (bit << e) + make (more, e + 4n)

const print = n =>
console.log(n.toString(2))

// Test
for (let i=1; i<20; i++) {
print(make(Array(i).fill(15n))) // longer and longer array...
}

注意:如果您在运行上述命令时遇到错误,请使用 Chrome 重试...

关于javascript - 如何从八 (8) 个 4 位整数创建 32 位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55390991/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com