border2Int行为的边框情况

时间:2013-05-27 19:11:10

标签: haskell ghc

对于64位计算机,

float2Int似乎在2^^622^^63之间的某处溢出(我在使用GHC 7.6.1的intel iMac上尝试过它)。我在尝试检查maxBound Int时发现了这个问题。 float2Int在GHC中作为primop float2Int#实现。

我的intel mac上的GHCi提示输出低于 - maxBound::Int2^^63。我还尝试将2^^63转换为Float,然后稍微减少值以查看溢出是否消失(如果有的话,考虑到小的舍入错误)。它没有:

λ: 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之前正常工作,并在2^^622^^63之间的某处溢出。我查了GHC trac,看看是否有任何报告错误,并没有发现任何错误。关于这个,我没有找到关于SO的任何帖子。

1 个答案:

答案 0 :(得分:8)

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

  

maxBound :: Int在我的intel 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

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