Reputation: 25812
Assume the system is 32 bits.
For a word, OCaml reserves the least significant bit to identify it is a pointer or an integer. So for an integer, there are only 31 bits effective.
I wish to know what OCaml does exactly for this conversion.
For example, if I do let x = 1
, does OCaml do the followings?
0000...0001
0000...0010
1
to it to make it appear like an integer: 0000...0011
Am I correct?
But if this is the case, how does OCaml deal with negative integer such as let x = min_int
?
1000...000
000...000
1
: 000...0001
Then the negative sign is lost, right?
In addition, how about the reversed process, i.e., what will OCaml do when it find a word in heap is an integer?
Upvotes: 1
Views: 147
Reputation: 66803
Here is some OCaml code (ints.ml):
let x = 1
let y = min_int
Here is the code generated for i386 (32-bit) architecture:
.text
.align 4
.globl _camlInts__entry
_camlInts__entry:
subl $12, %esp
L100:
movl $0x3, _camlInts
movl $0x80000001, _camlInts + 4
movl $0x1, %eax
addl $12, %esp
ret
So (A) OCaml representation for 1 is 0b11 and for min_int
is 0b1000....1. (B) The generated code doesn't "do" anything other than load the value (i.e., the int value isn't computed at run time from the usual integer value).
To add two OCaml int values: clear lowest bit of one of them, then add as usual.
Upvotes: 0
Reputation: 41180
First of all, a symmetric issue exists for large positive values. You will convert the sign of max_int
as well.
Rather than left shift, think of the conversion as: x * 2 + 1
So, your representable numbers are limited to min_int / 2
to max_int / 2
[due to the representation of integers using twos complement, this is not really symmetric, the real limits are min_int / 2 - 1
to max_int / 2
]
The conversion back to integer is simply m / 2
Most processors have an "arithmetic shift" instruction that shifts right preserving (duplicating) the sign bit.
Upvotes: 1