swang
swang

Reputation: 5249

Haskell Int size

What's the size of Int (bounded integer) in Haskell, or should I say in GHC?

As practice I wrote a short program to get the number of bits set in an 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)

If I input number -1, the result is 64, which indicates the size of an Int is 64 bit. Why is that the case? Why it's not 32 bit as in C/C++?

Upvotes: 3

Views: 5333

Answers (3)

wsaleem
wsaleem

Reputation: 642

The previous replies do not answer the question, "What's the size of Int", rather provide methods to find the extreme values.

Data.Bits provides bitSizeMaybe and finiteBitSize to find out the bit size of a type. These supersede bitSize from the same module.

finiteBitSize :: b -> Int

Return the number of bits in the type of the argument. The actual value of the argument is ignored.

finiteBitSize = bitSize
bitSizeMaybe = Just . finiteBitSize

Example usage:

> import Data.Bits
> finiteBitSize (42 :: Int)
64

Upvotes: 3

leftaroundabout
leftaroundabout

Reputation: 120711

To answer why it's done this way in Haskell: unlike C and C++, Haskell implementations by default "box" everything, even primitive types. This is necessary for much of the amazing polymorphism features (though, even more amazingly, inlining can often get you rid of most of the incured overhead), as well as lazyness. As a result, even Bool takes up at least the memory of a generic pointer: 64 bits on a AMD64 platform! May sound very wasteful, but seldom an issue: during processing, all data is loaded in a few registers which are this big anyway, and for storage you can always use more efficient "packed" containers. At any rate, this means it doesn't really have any advantage use a type with 32 data bits vs. one with 64 bits for calculations, whilst on a 64-bit architecture. But obviously there are plenty of situations where the extra bits come in handy; when you know you'll need them you can always ask explicitly for Int64. But that is then costly in an actually relevant sense while you're working on a 32-bit platform, because there the memory will like be much tighter as well.

Often, when big numbers could turn up but aren't really typical, it's more efficient to just use the "native" type but check on maxBound to avoid overflows.

Upvotes: 7

Oscar Robinson
Oscar Robinson

Reputation: 1003

The Int type is:

A fixed-precision integer type with at least the range [-2^29 .. 2^29-1]. The exact range for a given implementation can be determined by using minBound and maxBound from the Bounded class.

taken from the Haskell documentation.

You can use the types Int8 for 8bit ints, Int32 for 32 bit ints and Int64 for 64bit ints.

Source

Upvotes: 17

Related Questions