border2Int行为的边框情况

Sal*_*Sal 0 haskell ghc

float2Int似乎介于溢出2^^62,并2^^63为64位机器(我用GHC 7.6.1试图在英特尔的iMac).试图检查时,我才注意到这个问题maxBoundInt.在GHC中float2Int作为一个原始实现float2Int#.

GHCI提示输出低于- maxBound::Int2^^63我的Intel 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
Run Code Online (Sandbox Code Playgroud)

64位Int边界上的溢出是否是预期的行为?它似乎做工精细,直到2^^62和介于溢出2^^622^^63.我查了GHC trac,看看是否有任何报告错误,并没有发现任何错误.关于这个,我没有在SO上发现任何帖子.

Tho*_*son 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
Run Code Online (Sandbox Code Playgroud)

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

最后,

> 2^^62 + 2^^61 < (2^^63 :: Float)
True
Run Code Online (Sandbox Code Playgroud)

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