4

我正在编写一个 Haskell 到 Javascript 代码生成器,使用 GHC 作为库。由于 Javascript 没有整数类型,并且它的 Number 类型只能正确表示最大为 2⁵³ 的整数,因此我将整数表示为数字,显式执行所有算术模 2³²。这在 32 位 GHC 上效果很好,但在 64 位版本上效果更差。

GHC 很乐意将 Int64 值强制转换为 Int 并将 Int 常量解释为 64 位值(例如,0xffffffff 变为 4294967295 而不是 -1),这会导致各种烦人的问题。

如果标准库是在 32 位机器上构建的,编译器即使在 64 位系统上也能很好地处理“普通”网络内容,但是“请不要使用大数字,好吗?” 不是您想在编译器手册中看到的内容。使用 -O0 编译可以缓解一些问题(但不是全部),但是(不出所料)生成的代码不仅速度慢,而且太大。

所以,我需要阻止 GHC 假设 Int 和 Int64 是等价的。这甚至可能吗?

4

3 回答 3

7

如果不使用 32 位 GHC,这是不可能的。

Haskell 语言标准说你对类型的唯一了解Int就是它有

至少范围 [-2^29 .. 2^29-1

因此,您可以愉快地截断Int大于此值的值,并且仍然是完全符合 Haskell 2010 的实现!

但是,您可能不应该这样做,而是为 JavaScript 寻找 64 位整数类型。与例如 GHC 相同的技巧支持Int6432 位机器。

于 2012-05-08T12:20:06.717 回答
3

通常,“Int”应该只用于 2^29 足够大的东西,除此之外它并不重要。在其他任何地方使用整数或 Data.Word 或 Data.Int(Int8、Int16 等)类型之一。很好的例子包括大多数大小和计数(但不是文件大小,这些天很容易超过 2^32)

经典的坏例子:Control.Concurrent.threadDelay :: Int -> IO()。参数是以 uSec 为单位的暂停时间。2^29 uSec = 8.94784853 分钟(根据谷歌计算器)。参数应该是整数,或者至少是 Word64(584 554.531 年)。

于 2012-05-08T18:56:44.690 回答
1

Javascript 数字表示为双精度数,因此请使用Double.

于 2012-05-08T16:47:01.070 回答