使用整数值及其最大值

Working with values of integers and their maxes

The code fragment

int x = < an integer value >;
System.out.println(x*x);

displays -131071. Which of the following is a possible value of x?

显然答案是 2^16 - 1

我什至不知道那是一个怎样的答案选择。没有计算器我怎么解决这个问题?


The statement

System.out.println(Integer.MAX_VALUE);

prints 2147483647, which is equal to 2^31 - 1. What does the following statement print?

System.out.println(Integer.MAX_VALUE + 2);

答案是-2137483546。我很困惑,因为我们要越界,所以它不应该导致 ArithmeticException 吗?

我问这些问题不是让你帮我做的吗?如果你能给我推理而不仅仅是答案(我已经有了)?我只是对使用 ints 接近最大值的操作感到困惑。

我会以更有用的形式写 -131071:0xfffe0001

现在只需解决x * x == 0xfffe0001。显然 x 是奇数,否则它的平方永远不会是奇数。这个论点可以更进一步:模 216 我们得到 x * x = 1,所以 x 是 1 或 -1 模 216 因为它们是 1 的唯一平方根。

所以低16位只有两个选择,高16位呢?

首先让我们为低 16 位尝试 0xffff(又名 -1 模 216)。那(即高 16 位为零)立即证明有效,但 "by calculation" 一个无聊的理由。这是一个更好的理由:原始数字是 232-217+1(从其十六进制表示中很容易看出),这会影响 (2 16-1)2,照常做"reverse square",所以232是 a2, -217 = 2ab 和 1 = b2.

但这只是一种可能,还有更多:

  • 0x0000ffff = 216-1
  • 0x8000ffff = 231+216-1(231抵消 如果你平方)

还记得低 16 位怎么会是 1 吗?这也给出了 2 种可能性:

  • 0x7fff0001
  • 0xffff0001

shouldn't it cause an ArithmeticException since we're going out of bounds?

没有使用标准的换行算法,但请参阅 Math.multiplyExact 和朋友。在正常的运算符中,/% 可以抛出,其他的还好安全。