Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit Size of GHC's Int Type

Tags:

Why is GHC's Int type not guaranteed to use exactly 32 bits of precision? This document claim it has at least 30-bit signed precision. Is it somehow related to fitting Maybe Int or similar into 32-bits?

like image 529
Nordlöw Avatar asked Oct 16 '11 19:10

Nordlöw


People also ask

How is int defined in Haskell?

Int is defined to be a signed integer with a range of at least [-2^29, 2^29) . – Aaron Friel.

Is Haskell an integer?

Haskell has two integral types, namely Int and Integer . Int is the type of limited-precision integers; this means that there is a smallest integer of type Int , namely minBound , and a greatest integer of type Int , namely maxBound .

What is the difference between int and integer in Haskell?

What's the difference between Integer and Int ? Integer can represent arbitrarily large integers, up to using all of the storage on your machine. Int can only represent integers in a finite range.


2 Answers

It is to allow implementations of Haskell that use tagging. When using tagging you need a few bits as tags (at least one, two is better). I'm not sure there currently are any such implementations, but I seem to remember Yale Haskell used it.

Tagging can somewhat avoid the disadvantages of boxing, since you no longer have to box everything; instead the tag bit will tell you if it's evaluated etc.

like image 200
augustss Avatar answered Nov 15 '22 12:11

augustss


The Haskell language definition states that the type Int covers at least the range [−229, 229−1]. There are other compilers/interpreters that use this property to boost the execution time of the resulting program.

All internal references to (aligned) Haskell data point to memory addresses that are multiple of 4(8) on 32-bit(64-bit) systems. So, references need only 30bits(61bits) and therefore allow 2(3) bits for "pointer tagging".

In case of data, the GHC uses those tags to store information about that referenced data, i.e. whether that value is already evaluated and if so which constructor it has.

In case of 30-bit Ints (so, not GHC), you could use one bit to decide if it is either a pointer to an unevaluated Int or that Int itself.

Pointer tagging could be used for one-bit reference counting, which can speed up the garbage collection process. That can be useful in cases where a direct one-to-one producer-consumer relationship was created at runtime: It would result directly in memory reuse instead of a garbage collector feeding.

So, using 2 bits for pointer tagging, there could be some wild combination of intense optimisation... In case of Ints I could imagine these 4 tags:

  • a singular reference to an unevaluated Int
  • one of many references to the same possibly still unevaluated Int
  • 30 bits of that Int itself
  • a reference (of possibly many references) to an evaluated 32-bit Int.
like image 32
comonad Avatar answered Nov 15 '22 13:11

comonad