问题描述
我有一些包含大量数字的数据,这些数据我读入并存储为字符串。我需要将它们转换为十六进制字符串,但是当我尝试使用 BigInt(decimalString).toString(16) 时,由于仍然截断了十六进制值的最后一个字符,因此不会保留 bigInt 类型。
const decimal = '18446744072635809797'
console.log(decimal)
// Expected: 18446744072635809797 Actual: 18446744072635810000 FAIL
console.log(BigInt(decimal))
// Expected: 18446744072635809792n Actual: 18446744072635809792n SUCCESS
console.log(BigInt(decimal).toString(16))
// Expected: ffffffffc0000005 Actual: "ffffffffc0000000 FAIL
最奇怪的部分是在 JSfiddle 中尝试相同的代码完全按预期工作,但在我的环境中却没有。这是我的 tsconfig:
{
"compilerOptions": {
"target": "ES5","lib": ["dom","dom.iterable","esnext","ESNext.BigInt"],"allowJs": true,"skipLibCheck": true,"esModuleInterop": true,"allowSyntheticDefaultImports": true,"strict": true,"forceConsistentCasingInFileNames": true,"noFallthroughCasesInSwitch": true,"module": "esnext","moduleResolution": "node","resolveJsonModule": true,"isolatedModules": true,"noEmit": true,"jsx": "react-jsx"
},"include": ["src"]
}
我发现浏览器(Edge 和 Chrome)之间也发生了相同的行为。我错过了什么?
json文件基本上是这样的 { 一:18446744072635809797 } 我使用接口将其保存到 javascript 对象以将其转换为字符串:
interface IData{
a: string
}
service.GetData().then((data: IData) => {
if(data.a > Number.MAX_SAFE_INTEGER){
const decimal = BigInt(data.a)
// attempt to convert decimal to hex
}
})
解决方法
json文件基本上是这样的{ a: 18446744072635809797 }
那是你的问题:值是一个数字,并被解析为一个数字。 JSON 应该是 { a: "18446744072635809797" }
,然后您可以通过将此字符串传递给 BigInt
函数来获得您期望的行为,例如BigInt(data.a).toString(16)
。
TypeScript 接口定义不会导致执行任何转换。即使是这样,当 JSON.parse
返回时也已经太晚了,因为无法存储在 Number
中的位在那时已经丢失了。
亲眼看看:
> JSON.parse('{ "a": 18446744072635809797 }')
← {a: 18446744072635810000}
> JSON.parse('{ "a": "18446744072635809797" }')
← {a: '18446744072635809797'}