0

I want to provide the actual page based on the entry index of a table's element. I use PageRequest.of(int page, int size).

I have the index which is passed down to the function, and a constant PAGESIZE_SEARCH which is 50.

I want to pass the current page according to the index as follows:

PageRequest.of((int) index/PAGESIZE_SEARCH, PAGESIZE_SEARCH)

My IDEA (IntelliJ Ultimate 2020.1.1) greys my casting out and hinting Casting 'index' to 'int' is redundant. If I delete the cast even the compiler accepts it and I also don't get a Runtime Exception.

Why is this? Isn't the divsion unsafe there? Any explanation would be appreciated.

leachim
  • 89
  • 1
  • 10
  • 10
    Why do you consider it unsafe? The behavior is well specified. It performs an integer division. – Federico klez Culloca Jul 20 '20 at 09:22
  • You're right. My bad. I come from other programming languages, didn't read the java specification. Thanks – leachim Jul 20 '20 at 09:24
  • It is useful and in many cases does exactly what is needed. Note: All numerical operations have limitiations, and you need to be aware of them to be able to use them correctly. – Hulk Jul 20 '20 at 09:24
  • @leachim Other programming languages also provide integer division, though some offer a different operator. – Slaw Jul 20 '20 at 09:27
  • Several languages made the same design choice of implicitly using integer division: C, C# and C++, for example. – Hulk Jul 20 '20 at 09:40
  • btw `(int) index/PAGESIZE_SEARCH` is not doing what you think it's doing. It's not `(int) (index / PAGESIZE_SEARCH)`. It's `((int) index) / PAGESIZE_SEARCH` – Michael Jul 20 '20 at 09:42
  • Related (duplicate, but unanswered). A few interesing comments: https://stackoverflow.com/questions/22341128/why-integer-division-java – Hulk Jul 20 '20 at 09:48

2 Answers2

5

The division isn't unsafe; it does exactly as it should do.

Dividing two integers is known as an integer division and simply returns the result of dividing the two numbers without the remainder.

Also, as pointed out in the comments, you're actually casting index to an int, rather than index/PAGESIZE_SEARCH - think about using brackets to be more precise: (int) (index / PAGESIZE_SEARCH).

EDIT: You can read more on this topic here.

Reece Coombes
  • 374
  • 1
  • 9
5

Mathematically speaking, the integers are not closed under divisison, meaning that the result of dividing two arbitrary integer like 3 and 5 may result in something that can not be represented by an integer. Each mathematical set of numbers (be it N, ℤ, ℚ, ℝ, ℂ) has certain limitations, and each of the representations of these sets in a computer has limitations as well. Understanding those limitations is a somewhat important point.

Wrt. division of two integers not being closed, you can deal with this in five different ways, mathematically speaking:

  • Making division a partial function. This isn't desirable for a programming language that has to deal with arbitrary inputs. Do you get an arithmetic exception every time you try to divide numbers for which division is undefined? Not really a good approach.
  • Make division a function from the integer to the real numbers. This is actually an approach you can use, but real numbers can not be represented exactly in computing hardware, so its only in approximate solution. Its certainly possible to implement programming languages this way, but in practice you are more likely interested in an integer result.
  • Give the answer as a fractional result (Q). e.g. 3/5 becomes ⅗, sometimes represented as the tuple (3,5). You can do something like this in some programming languages, e.g. Haskell.
  • Give the answer as quotient and remainder. Some programming languages do this, but Java does not support tuple types nor multiple return values, so this is out. This is sometimes called euclidean division.
  • Give only the quotient as answer, discard the remainder. This is often called integer division, and is what Java implements. You can recover the remainder via a related operation, the modulo operator %.

The JLS specifies how division works in §15.7.2:

Integer division rounds toward 0. That is, the quotient produced for operands n and d that are integers after binary numeric promotion (§5.6.2) is an integer value q whose magnitude is as large as possible while satisfying |d ⋅ q| ≤ |n|. Moreover, q is positive when |n| ≥ |d| and n and d have the same sign, but q is negative when |n| ≥ |d| and n and d have opposite signs.

There is one special case that does not satisfy this rule: if the dividend is the negative integer of largest possible magnitude for its type, and the divisor is -1, then integer overflow occurs and the result is equal to the dividend. Despite the overflow, no exception is thrown in this case. On the other hand, if the value of the divisor in an integer division is 0, then an ArithmeticException is thrown.

Moreover, you are not actually casting the result of the division to int. You are only casting index to an int. The cast is irrelevant and redundant, because integer divisions returns an int, as explained above.

Polygnome
  • 7,159
  • 2
  • 30
  • 55