0

float2Int2^^62似乎在 64位机器之间溢出2^^63(我在带有 GHC 7.6.1 的英特尔 iMac 上尝试过)。我只是在尝试检查maxBoundfor时注意到了这个问题Int。在 GHC 中float2Int作为 primop 实现。float2Int#

GHCi 提示输出如下 -maxBound::Int2^^63我的英特尔 mac 上。我还尝试强制转换2^^63Float,然后稍微减小值以查看溢出是否消失(以解决小舍入错误(如果有)。它没有:

λ: maxBound :: Int
9223372036854775807
λ: GHC.Float.float2Int $ 2^^63 -- overflows
-9223372036854775808
λ: GHC.Float.float2Int $ (9223372036854775807::Float) -- now try actual value of 2^^63
-9223372036854775808
λ: GHC.Float.float2Int $ (9223372036854000000::Float)  -- reduce it a bit
-9223372036854775808
λ: minBound :: Int -- overflow value is same as minBound::Int
-9223372036854775808
λ: GHC.Float.float2Int $  2^^62 + 2^^61 -- works fine here
6917529027641081856

64 位 Int 边界上的这种溢出是预期的行为吗?它似乎工作正常,直到,并且在和2^^62之间的某个地方溢出。我查找了 GHC trac 以查看是否有任何报告的错误,但没有发现任何错误。我也没有在 SO 上找到任何关于这个的帖子。2^^622^^63

4

1 回答 1

8

这都是正确的行为。首先,让我们澄清一个小细节:

maxBound::Int 在我的英特尔 mac 上是 2^^63

不,应该是(2^63) - 1。减一非常重要,所以float2Int (2^^63)应该溢出。

现在你的减价怎么样?考虑一下:

Prelude GHC.Float.RealFracMethods> let a = 9223372036854775807::Float
Prelude GHC.Float.RealFracMethods> let b = 9223372036854000000::Float
Prelude GHC.Float.RealFracMethods> a == b
True

浮点数是近似值,您的减少不会导致浮点数发生重大变化。到目前为止的输入都等于2^63

最后,

> 2^^62 + 2^^61 < (2^^63 :: Float)
True

在您上次的测试中,您发现了一个数字,当转换为浮点数时,它表示为小于2^63,因此在 64 位范围内Int并产生您的预期值。

于 2013-05-27T19:55:52.377 回答