为什么PHP中没有整数“下溢”?

时间:2015-05-09 07:29:02

标签: php binary signed

如果我在PHP中这样做:

echo (int)9223372036854775808;

输出是-9223372036854775808,这是完美的,因为9223372036854775807二进制是:

0111 ... 1

即,0后跟63个。显然,二进制中的1只是1,所以当我添加它时,我得到1000 ... 0(1之后有63 0),这是2s补码表示的-9223372036854775808。

所以我希望如果我做了类似添加-1到-9223372036854775808的东西,我会回来9223372036854775807.4位二进制的类比就像:

1000   (-8)
1111   (-1)
----
0111   (7)

据我所知,我不能简单地将-9223372036854775809分配给变量,因为在64位有符号整数中没有表示,但为什么这不起作用:

$smallest_int = (int)-9223372036854775808;

echo (int)($smallest_int-1); //similar to 1000+1111 in 4 bit

当我运行它时,输出仍然是-9223372036854775808。为什么会这样?这与PHP的弱打字有关吗?这是否会发生在其他语言中(我知道它肯定不会发生在C语言中)?

2 个答案:

答案 0 :(得分:0)

9223372036854775808成为-9223372036854775808确实如此,但它并不像仅仅"整数环绕"那么简单。以下是一些映射(通过实验找到):

  • 922337203685477580 9 →仍然-9223372036854775808( -922337203685477580 7
  • 92233720368547758 10 →仍然-9223372036854775808( -922337203685477580 6

所以你可能认为int范围之外的数字都被映射到-9223372036854775808 - 但是等等! :

  • 9 3 23372036854775810→-9 1 23372036854775808
  • 9223372036854775808 0 →0

对我来说,所有这些似乎都是武断的。我认为发生的事情是超过18位数的值(因此很容易被识别为在整数范围之外)基本上被丢弃并替换为零,而18位长的值被解析以防万一在范围内,但使用的逻辑不是为超出范围的值而设计的,并且不是为了连贯。

答案 1 :(得分:-1)

我在这里猜测,因为数字没有输入,PHP实际上是将你的数字转换为浮动,然后在数学中丢失-1。