如果结果必须是 int,为什么 Java 编译器允许 int/int 除法?

lea*_*him 0 java pageable

我想根据表元素的条目索引提供实际页面。我用PageRequest.of(int page, int size).

我有index传递给函数的 ,以及一个PAGESIZE_SEARCH50的常量。

我想根据索引传递当前页面如下:

PageRequest.of((int) index/PAGESIZE_SEARCH, PAGESIZE_SEARCH)
Run Code Online (Sandbox Code Playgroud)

我的 IDEA(IntelliJ Ultimate 2020.1.1)使我的投射和暗示变灰 Casting 'index' to 'int' is redundant。如果我删除演员表,即使编译器接受它,我也不会收到运行时异常。

为什么是这样?那里的部门不是不安全吗?任何解释将不胜感激。

小智 5

该部门并非不安全;它完全按照它应该做的。

将两个整数相除称为整数除法,它只返回两个数相除而没有余数的结果。

此外,正如评论中所指出的,您实际上是在转换index为 int,而不是index/PAGESIZE_SEARCH- 考虑使用括号更精确:(int) (index / PAGESIZE_SEARCH)

编辑:您可以在此处阅读有关此主题的更多信息


Pol*_*ome 5

从数学上讲,整数在除法下不是封闭的,这意味着将两个任意整数(如 3 和 5)相除的结果可能会导致无法用整数表示的结果。每组数学数字(无论是 N、?、?、?、?)都有一定的局限性,并且这些数字在计算机中的每个表示形式也有局限性。了解这些限制是很重要的一点。

写的。不封闭的两个整数的除法,你可以用五种不同的方式来处理这个问题,从数学上讲:

  • 使除法成为偏函数。这对于必须处理任意输入的编程语言来说是不可取的。每次尝试对未定义除法的数字进行除法时,是否都会遇到算术异常?不是一个很好的方法。
  • 使除法成为从整数到实数的函数。这实际上是您可以使用的一种方法,但是在计算硬件中无法准确表示实数,因此只能使用近似解。以这种方式实现编程语言当然是可能的,但在实践中,您更有可能对整数结果感兴趣。
  • 以分数结果 (Q) 形式给出答案。例如 3/5 变成 ?,有时表示为元组 (3,5)。您可以在某些编程语言中执行类似的操作,例如 Haskell。
  • 给出商和余数的答案。一些编程语言会这样做,但 Java 不支持元组类型或多返回值,所以这是过时的。这有时称为欧几里得除法
  • 只给出商作为答案,丢弃余数。这通常称为整数除法,这是Java 实现的。您可以通过相关操作(模运算符)恢复余数%

JLS 在§15.7.2 中指定了除法的工作方式

整数除法向 0 舍入。也就是说,在二进制数值提升(第 5.6.2 节)后为整数的操作数 n 和 d 产生的商是整数值 q,其大小在满足 |d 的同时尽可能大?q| ? |n|。此外,当 |n| 时 q 为正数 ? |d| 并且 n 和 d 具有相同的符号,但当 |n| 时 q 为负数 ? |d| n 和 d 的符号相反。

有一种特殊情况不满足此规则:如果被除数是其类型的最大可能数量级的负整数,并且除数为-1,则发生整数溢出并且结果等于被除数。尽管溢出,但在这种情况下不会引发异常。另一方面,如果整数除法中的除数值为 0,则抛出 ArithmeticException。

此外,您实际上并没有将除法的结果转换为int. 您只是投射indexint. 转换是无关的和多余的,因为整数除法返回一个int,如上所述。