如何在 Go 中将 Float64 转换为 Base36?

问题描述 投票:0回答:2

我说过值

0.36388617850285954
,当我使用Javascript
.toString(36)
函数时,我得到输出
"0.d3lh1pogpwk".
我想在golang中复制它,但是我没有真正的起点。

我将如何执行此操作?

go floating-point radix base36
2个回答
3
投票

Go base36 包无法正确转换它,因为 Javascript 的

toString(36)
不会对 float64 进行 Base36 编码,它使用基数 36 来表示它。关于此函数如何在
Number
对象上工作的细节,文档缺乏亮点(并且只有数字对象),并且逻辑也确实很奇怪,但位于此处:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString#说明

基本上,在非整数的情况下,通过将小数点左侧的转换与点连接起来,然后将转换值转换为以N为基数的数字(其中N是传入的基数)小数点右边的。例如

baseNLeft + "." + baseNRight

上面的文档链接中还解释了有关底片的其他注意事项。具体来说,它们保留负数并简单地转换数字,然后替换负号,而不是使用二进制补码表示形式。

在我看来,此功能不适合除 Javascript 本身之外的任何其他语言,我建议谨慎跨语言使用它。

关于问题本身的答案,即如何在 Go 中做到这一点。遵循相同的愚蠢语义,并对数十万个测试用例进行单元测试,以检查 Javascript 和 Go 实现中的

f(x) = y
。逻辑的实际规范位于 ECMA 规范中:https://www.ecma-international.org/ecma-262/6.0/#sec-tostring-applied-to-the-number-type

注意:Go 中有一个名为

otto
(github.com/robertkrimen/otto) 实现的 Javascript 引擎,但它不能正确执行
Number.toString(radix)
功能。另外,如果这是它的唯一目的,那么它是一个需要导入的繁重的库。


0
投票

在尝试从线程 ID 生成 Twitter/X 令牌时,我遇到了类似的问题。虽然最初的函数是用 JavaScript 编写的,并且我认为实现起来很简单,但结果比预期的要复杂。

需要注意的是,

.toString(X)
的 JavaScript 实现存在一些问题,但由于担心向后兼容性,这些问题不太可能得到修复。

我在 Go 中解决了这个问题,并获得了一致且准确的结果。我创建了一个公共要点,我已使用您的示例对其进行了更新:

https://gist.github.com/the-hotmann/a745c76c806128db68700685105a20e8#file-twittergettoken-go-L38-L43

© www.soinside.com 2019 - 2024. All rights reserved.