JavaScript BigInt 打印无符号二进制表示
JavaScript BigInt print unsigned binary represenation
使用 JavaScript 的 BigInt
时如何打印无符号整数?
BigInt
s 可以使用 toString(2)
打印为二进制表示。但是,对于负值,此函数仅在打印时附加一个 -
符号。
BigInt(42).toString(2)
// output => 101010
BigInt(-42).toString(2)
// output => -101010
如何打印 BigInt(42)
的无符号表示?我认为使用常规 number
s 你可以做 (-42 >>> 0).toString(2)
,但是 BigInt
似乎没有实现无符号右移,导致错误
(BigInt(-42) >>> BigInt(0)).toString(2)
// TypeError: BigInts have no unsigned right shift, use >> instead
下面是将 64 位 BigInts 转换为二进制字符串的方法:
// take two's complement of a binary string
const twosComplement = (binaryString) => {
let complement = BigInt('0b' + binaryString.split('').map(e => e === "0" ? "1" : "0").join(''));
return decToBinary(complement + BigInt(1));
}
const decToBinary = (num) => {
let result = ""
const isNegative = num < 0;
if (isNegative) num = -num;
while (num > 0) {
result = (num % BigInt(2)) + result;
num /= BigInt(2);
}
if (result.length > 64) result = result.substring(result.length - 64);
result = result.padStart(64, "0");
if (isNegative) result = twosComplement(result);
return result;
}
console.log(decToBinary(BigInt(5))); // 0000000000000000000000000000000000000000000000000000000000000101
console.log(decToBinary(BigInt(-5))); // 1111111111111111111111111111111111111111111111111111111111111011
但是,此代码不进行任何验证。
获取负 BigInt 的二进制补码表示的一种简单方法是使用 BigInt.asUintN(bit_width, bigint)
:
> BigInt.asUintN(64, -42n).toString(2)
'1111111111111111111111111111111111111111111111111111111111010110'
注意:
- 您必须定义所需的位数(在我的示例中为 64),对此没有“自然”/自动值。
- 仅给定该二进制数字串,无法判断这是一个正 BigInt(值接近 2n**64n)还是 -42n 的二进制补码表示。因此,如果您想稍后反转转换,则必须以某种方式提供此信息(例如,通过编写代码使其隐含地假定一个或另一个选项)。
- 相关地,这不是
-42n
在当前浏览器中的内部存储方式。 (但这并不需要您担心,因为您可以随时 want/need 创建此输出。)
- 您可以通过减法获得相同的结果:
((2n ** 64n) - 42n).toString(2)
-- 同样,您可以指定要查看的位数。
Is there something like bitAtIndex
for BigInt
?
不,因为没有关于如何表示 BigInt 的规范。引擎可以选择以他们想要的任何方式使用位,只要生成的 BigInts 的行为符合规范要求。
@Kyroath:
negative BigInts are represented as infinite-length two's complement
不,它们不是:当前浏览器中的实现将 BigInts 表示为“符号 + 大小”,而不是二进制补码。然而,这是一个无法观察到的实现细节:实现可能会改变它们在内部存储 BigInts 的方式,而 BigInts 的行为将完全相同。
您可能想说的是,任何负整数(大或小)的二进制补码表示在概念上都是无限的 1 位流,因此在有限 space 中打印或存储它总是需要定义一些 characters/bits 之后流被简单地切断。当你有一个固定宽度的类型时,这显然定义了这个分界点;对于概念上无限的 BigInts,您必须自己定义它。
使用 JavaScript 的 BigInt
时如何打印无符号整数?
BigInt
s 可以使用 toString(2)
打印为二进制表示。但是,对于负值,此函数仅在打印时附加一个 -
符号。
BigInt(42).toString(2)
// output => 101010
BigInt(-42).toString(2)
// output => -101010
如何打印 BigInt(42)
的无符号表示?我认为使用常规 number
s 你可以做 (-42 >>> 0).toString(2)
,但是 BigInt
似乎没有实现无符号右移,导致错误
(BigInt(-42) >>> BigInt(0)).toString(2)
// TypeError: BigInts have no unsigned right shift, use >> instead
下面是将 64 位 BigInts 转换为二进制字符串的方法:
// take two's complement of a binary string
const twosComplement = (binaryString) => {
let complement = BigInt('0b' + binaryString.split('').map(e => e === "0" ? "1" : "0").join(''));
return decToBinary(complement + BigInt(1));
}
const decToBinary = (num) => {
let result = ""
const isNegative = num < 0;
if (isNegative) num = -num;
while (num > 0) {
result = (num % BigInt(2)) + result;
num /= BigInt(2);
}
if (result.length > 64) result = result.substring(result.length - 64);
result = result.padStart(64, "0");
if (isNegative) result = twosComplement(result);
return result;
}
console.log(decToBinary(BigInt(5))); // 0000000000000000000000000000000000000000000000000000000000000101
console.log(decToBinary(BigInt(-5))); // 1111111111111111111111111111111111111111111111111111111111111011
但是,此代码不进行任何验证。
获取负 BigInt 的二进制补码表示的一种简单方法是使用 BigInt.asUintN(bit_width, bigint)
:
> BigInt.asUintN(64, -42n).toString(2)
'1111111111111111111111111111111111111111111111111111111111010110'
注意:
- 您必须定义所需的位数(在我的示例中为 64),对此没有“自然”/自动值。
- 仅给定该二进制数字串,无法判断这是一个正 BigInt(值接近 2n**64n)还是 -42n 的二进制补码表示。因此,如果您想稍后反转转换,则必须以某种方式提供此信息(例如,通过编写代码使其隐含地假定一个或另一个选项)。
- 相关地,这不是
-42n
在当前浏览器中的内部存储方式。 (但这并不需要您担心,因为您可以随时 want/need 创建此输出。) - 您可以通过减法获得相同的结果:
((2n ** 64n) - 42n).toString(2)
-- 同样,您可以指定要查看的位数。
Is there something like
bitAtIndex
forBigInt
?
不,因为没有关于如何表示 BigInt 的规范。引擎可以选择以他们想要的任何方式使用位,只要生成的 BigInts 的行为符合规范要求。
@Kyroath:
negative BigInts are represented as infinite-length two's complement
不,它们不是:当前浏览器中的实现将 BigInts 表示为“符号 + 大小”,而不是二进制补码。然而,这是一个无法观察到的实现细节:实现可能会改变它们在内部存储 BigInts 的方式,而 BigInts 的行为将完全相同。
您可能想说的是,任何负整数(大或小)的二进制补码表示在概念上都是无限的 1 位流,因此在有限 space 中打印或存储它总是需要定义一些 characters/bits 之后流被简单地切断。当你有一个固定宽度的类型时,这显然定义了这个分界点;对于概念上无限的 BigInts,您必须自己定义它。