Haskell中Int(有界整数(的大小是多少,或者我应该说在GHC中是多少?
在实践中,我写了一个短程序来获取Int 中设置的位数
import Data.Bits
getBits :: Int -> Int
getBits x
| x == 0 = 0
| otherwise = 1 + (getBits y)
where y = x .&. (x - 1)
main = do
putStrLn "type a integer"
num <- getLine
let n = read num :: Int
putStrLn $ "result is: " ++ show (getBits n)
如果我输入数字-1,结果是64,这表明Int的大小是64位。为什么会这样?为什么它不像C/C++那样是32位?
Int类型为:
一个固定精度的整数类型,其范围至少为[-2^29。。2^29-1]。给定实现的确切范围可以确定通过使用Bounded类中的minBound和maxBound。
取自Haskell文档。
可以使用类型Int8表示8位整数,Int32表示32位整数,而Int64表示64位整数。
源
为了回答为什么在Haskell中这样做:与C和C++不同,Haskell实现默认情况下"框"所有内容,甚至是基元类型。这对于许多令人惊叹的多态性特性(尽管更令人惊讶的是,内联通常可以消除大部分引入的开销(和懒惰来说是必要的。因此,即使是Bool
也至少占用通用指针的内存:在AMD64平台上为64位!听起来可能很浪费,但很少有问题:在处理过程中,所有数据都加载在几个寄存器中,这些寄存器无论如何都这么大,对于存储,您总是可以使用更高效的"打包"容器。无论如何,这意味着在64位体系结构上,使用具有32个数据位的类型与使用具有64位的类型进行计算相比并没有任何优势。但很明显,在很多情况下,额外的部分都派上了用场;当你知道你需要它们时,你总是可以明确要求Int64
。但当你在32位平台上工作时,从实际意义上讲,这是非常昂贵的,因为那里的内存也会更紧。
通常,当大数字可能出现但不是真正典型的数字时,只使用"本机"类型但检查maxBound
以避免溢出会更有效。
前面的回复没有回答"Int的大小是多少"的问题,而是提供了找到极值的方法。
Data.Bits提供bitSizeMaybe
和finiteBitSize
来找出类型的比特大小。它们取代了来自同一模块的bitSize
。
finiteBitSize :: b -> Int
返回参数类型中的位数。实际参数的值被忽略。
finiteBitSize = bitSize
bitSizeMaybe = Just . finiteBitSize
示例用法:
> import Data.Bits
> finiteBitSize (42 :: Int)
64