我测试了一些代码:
var B: Byte; I: Integer; begin I := -10; B := I; end;
我希望看到变量In的结果是数字10(因为这是整型的低位字节),但结果是B =〉246。从逻辑上讲,我理解246 = 256 - 10,但我不明白为什么会发生这种情况?
v8wbuo2f1#
值为-10的整数的最低有效(ls)字节的期望值为10不正确。负数是根据一个叫做2的补码的系统来编码的,其中一个4字节整数值-1被编码为$FFFFFFFF,-2被编码为$FFFFFFFE,-3被编码为$FFFFFFFD... -10被编码为$FFFFFFF6......等等。这是目前大多数计算机/软件使用的系统。还有其他的系统,你可能会想到一个叫做Signed magnitude的系统(见:https://en.wikipedia.org/wiki/Signed_number_representations),其中最高有效位在被设置时指示负值,并且其中实际数字对于负数和正数被相同地编码(具有定义两个零值+0和-0的不便)。
flvlnr442#
值-10是Integer中的$FFFFFFF6,将其赋给一个较小宽度的类型将简单地截断该值-这意味着B中的值将是$F6,即246。如果使用range checking编译,则会出现异常,因为-10不适合Byte。如果你想把负数变成正数,你需要使用Abs函数。
-10
Integer
$FFFFFFF6
B
$F6
246
Byte
2条答案
按热度按时间v8wbuo2f1#
值为-10的整数的最低有效(ls)字节的期望值为10不正确。
负数是根据一个叫做2的补码的系统来编码的,其中一个4字节整数值-1被编码为$FFFFFFFF,-2被编码为$FFFFFFFE,-3被编码为$FFFFFFFD... -10被编码为$FFFFFFF6......等等。这是目前大多数计算机/软件使用的系统。
还有其他的系统,你可能会想到一个叫做Signed magnitude的系统(见:https://en.wikipedia.org/wiki/Signed_number_representations),其中最高有效位在被设置时指示负值,并且其中实际数字对于负数和正数被相同地编码(具有定义两个零值+0和-0的不便)。
flvlnr442#
值
-10
是Integer
中的$FFFFFFF6
,将其赋给一个较小宽度的类型将简单地截断该值-这意味着B
中的值将是$F6
,即246
。如果使用range checking编译,则会出现异常,因为
-10
不适合Byte
。如果你想把负数变成正数,你需要使用Abs函数。