我发现自己处于这样一种情况,我想将一个 BigInt 值转换为 Number 值。既然我知道我的值是一个安全整数,那么我该如何进行转换呢?
原来将它传递给Number
构造函数就像轻而易举的事情一样:
const myBigInt = BigInt(10); // `10n` also works
const myNumber = Number(myBigInt);
当然,需要记住您的 BigInt 值必须在 [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER] 范围内,这样转换才能正常工作,正如问题所述。+myBigInt
。 - MohammadparseInt
或Number
。
const large = BigInt(309);
const b = parseInt(large);
console.log(b);
const n = Number(large);
console.log(n);
parseInt
。是的,根据规范,parseInt
和Number
都应该将BigInt转换为字符串,然后再转换为数字进行转换。然而,与Number
的语义相比,尤其是在BigInt(number)
生成一个BigInt时,parseInt
的语义更加复杂,这使得浏览器厂商更有可能对Number(bigValue)
进行更多优化,而跳过内部的字符串处理过程。因此,建议使用Number
而不是parseInt
来提高性能。 - Jack GparseInt
和Number
有不同的行为,但是,为了将BigInt转换为数字,我想不出它们会有任何不同的情况。也许您可以提供一个例子,说明Number
和parseInt
在将BigInt转换为数字时有所不同,以便启发我。非常感谢。 - Jack GBigInts
这种情况下你是完全正确的,而我需要展示的是 parseInt
和 Number
有着不同的行为,具体在上面的链接中可以看到例子。 - I_Al-thamaryparseInt
时,最佳实践是使用基数。 - naveen编辑:请参见下面的评论讨论,了解为什么此答案是不正确的。无论如何我都会保留答案以进行澄清。
你应该使用以下任意一个静态方法:
BigInt.asIntN()
- 将 BigInt 值钳制(clamp)到有符号整数值,并返回该值。
BigInt.asUintN()
- 将 BigInt 值钳制(clamp)到无符号整数值,并返回该值。
N
暗示着 Number
,但实际上它们仍然返回 BigInt 值。尝试运行 typeof BigInt.asIntN(64, 1n)
,你会发现它报告的是 bigint
。所以这个答案实际上并没有回答问题。 - Lucio PaivaBigInt.asInt64(x)
和BigInt.asInt32(x)
,但为了最大限度的灵活性,决定只提供单个BigInt.asIntN(N,x)
。 - jmrkas(Ui|I)ntN
并不像你所说的那样,也不回答OP的问题。这些函数接受一个BigInt并返回模2^N的BigInt。 - Chris_FNumber.isSafeInteger
Number.isSafeInteger
,但是像下面这个简单的片段所示,即使BigInt
的值在Number
的最小和最大边界之内,利用该函数始终会返回false
。
console.log(Number.isSafeInteger(BigInt(1)))
// Returns false
这个实现利用了TS-Results库来返回成功或错误的响应,而不是像抛出异常那样处理。
如果你不想使用Results库,你可以选择返回值并在其他情况下抛出异常,或者根据你认为合适的方式进行处理。
import { Err, Ok, Result } from 'ts-results'
export function bigIntToNumber(value: bigint): Result<number, Error> {
if (validInterger(value)) {
return Ok(Number(value))
}
return Err(new Error(`Value: "${value}" is out of bounds to be a Number`))
}
function validInteger(value: bigint): boolean {
return value <= Number.MAX_SAFE_INTEGER && value >= Number.MIN_SAFE_INTEGER
}
有趣的是,JS的数字可以达到9,007,199,254,740,991
(即Number.MAX_SAFE_INTEGER
),而经典的4字节整数只能达到2,147,483,647
,因此JS的数字可以容纳更多,但不及8字节整数,后者可以达到9,223,372,036,854,775,807
。
正如评论中所指出的,超过Number.MAX_SAFE_INTEGER
的数字可以达到Number.MAX_VALUE
,仍然是有效的JS数字。您可以在这里阅读更多信息:
10_000_000_000_000_000_000
完全是一个有效的JS数字。我知道你的意思(2**53 - 1
在 2**31 - 1
和 2**63 - 1
之间,当然!),但这不是目前那段话的意思。另一种表达方式是:Number.MAX_SAFE_INTEGER
不等于 Number.MAX_VALUE
。您谈论的是前者,但JS数字“可以达到”(或“可以容纳”)后者。 - undefined