当我说'let x=1'(与31位相关)时,OCaml到底做了什么
假设系统是32位的 对于一个字,OCaml保留最低有效位来标识它是指针还是整数。因此,对于整数,只有31位有效 我想知道OCaml对这种转换到底做了什么当我说'let x=1'(与31位相关)时,OCaml到底做了什么,ocaml,Ocaml,假设系统是32位的 对于一个字,OCaml保留最低有效位来标识它是指针还是整数。因此,对于整数,只有31位有效 我想知道OCaml对这种转换到底做了什么 例如,如果我执行让x=1,OCaml是否执行以下操作 获取正常的32位1:0000…0001 将其向左移动1位:0000…0010 向其添加一个1,使其看起来像一个整数:0000…0011 我说得对吗 但如果是这种情况,OCaml如何处理负整数,例如let x=min_int 获取32位的正常最小值:1000…000 将其向左移动1位:000
例如,如果我执行
让x=1
,OCaml是否执行以下操作
0000…0001
0000…0010
1
,使其看起来像一个整数:0000…0011
let x=min_int
1000…000
000…000
1
:000…0001
此外,反向过程如何,即当OCaml在堆中发现一个字是整数时,它将做什么?首先,对于大正值存在对称问题。您还将转换
max_int
的符号
与左移不同,将转换视为:x*2+1
因此,您的可表示数字被限制为min\u int/2
到max\u int/2
[由于使用两个补码表示整数,这实际上不是对称的,实际限制是min\u int/2-1
到max\u int/2
]
返回整数的转换就是m/2
大多数处理器都有一条“算术移位”指令,它将保留(复制)符号位右移。以下是一些OCaml代码(ints.ml):
以下是为i386(32位)体系结构生成的代码:
.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
因此(A)1的OCaml表示为0b11,min\u int
的OCaml表示为0b1000….1。(B) 生成的代码除了加载值(即,在运行时不会从通常的整数值计算int值)之外,不会“执行”任何操作
要添加两个OCaml int值:清除其中一个值的最低位,然后像往常一样添加。OCaml的
minu int
是01000…000
@PascalCuoq是的,我知道,值应该是010…000
,我只是想找出您在问题中描述的转换过程(除了min_int
的值错误外:min_int
的实际值是010…000
,将其向左移动,并为非固定编码添加一个给定值10…0001
。符号位在它的位置上。@PascalCuoq那么你的意思是,如果我说让x=-1073741824(*min_int value*)
,OCaml将首先假定符号位必须位于第二个最高有效位,并根据31位进行2的补码?@PascalCuoq我在关于min\u int
的问题中写道,这种方式是因为我认为OCaml将首先假定32位,然后进行移位和相加。如果我说让x=-1073741824(*min\u int value*)
,OCaml将分配一个32位的字,首先假设符号位必须位于第二个最高有效位上,并根据31位执行2的补码。-1073741824
的二进制表示形式为0b11000000000000
——请注意,两个最高有效位是相同的。此条件适用于所有n左移1,不要“丢失”符号。不清楚“do 2的补码”是什么意思--1073741824
的值首先应该在2的补码中;然后只需左移并添加一个。你能回答这个问题吗
.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