【问题标题】:BigInt type isn't maintained in conversion to hex from decimal从十进制转换为十六进制时不维护 BigInt 类型
【发布时间】:2021-09-27 12:35:33
【问题描述】:

我有一些数据包含我读入并存储为字符串的大量数据。我需要将它们转换为十六进制字符串,但是当我尝试使用 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
  }
})

【问题讨论】:

  • 我不明白你的第一个FAIL。你只是在记录一个字符串,它不应该改变。
  • 你的意思是写decimal.toString()
  • 在 Windows 10 x64 上的 Edge 中我得到了正确的结果,实际上只是尝试了 1844674407263580979734234243423423424234323423423423423423423498992837497209387092387098723423423423459439803409850978345978 数字,它返回了 2ca5dfb8b507cc0c94b5770e8150988502caabf4a4060b810e6bc5abd7a42083b9dfb15d0bf197c8f9d0eb5891f5d110cf923fa
  • 那么你的环境比什么?
  • @Barmar 值在第一个 FAIL 中不同。我期望值在字符串中记录,但它记录它就好像它首先被转换为一个数字,所以它不太精确。添加“tostring()”不会改变这种行为

标签: javascript types hex bigint


【解决方案1】:

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'}

【讨论】:

    猜你喜欢
    • 2014-12-31
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 2018-11-18
    • 2011-07-28
    • 1970-01-01
    相关资源
    最近更新 更多