9

Besides divmod being a native instruction on many chipsets, it also is a lot easier on the eyes when subdividing a number in multiple different denominations

(which happens with e.g. milliseconds -> datetime conversion, or cents -> coin denomination conversion).

So is there a divmod that returns both the result of the division and of the remainder at the same time?

Qqwy
  • 5,214
  • 5
  • 42
  • 83
  • You are looking for getting the result of integer division and modulo operation in one single step? – luk2302 Oct 24 '17 at 08:36
  • Are you asking for a bytecode opcode, an operator or a method? – Kayaman Oct 24 '17 at 08:36
  • @Kayaman An operator or a method; either would be fine. Since my own searches so were unsuccessful, I'd expect there might not be an operator. – Qqwy Oct 24 '17 at 08:38
  • 1
    There is no such operations in Java. You may try `BigDecimal.divideAndRemainder()` for a method to return both values at the same time. – Alex Oct 24 '17 at 08:39
  • @luk2302 exactly.Because of the way arithmetic works in an ALU, both will be computed at the same time anyway. – Qqwy Oct 24 '17 at 08:39
  • Of course it's highly unlikely that you would need that (well, barring special cases). If you're doing milliseconds -> datetime conversions manually, you've already lost. – Kayaman Oct 24 '17 at 08:39
  • 1
    Afaik there is no such method, at least not one that employs the native instruction. But do you really need that? You can always use 2 operations and put them into a method if you want to but I guess you are after optimizations here. If that's the case, do you _really_ need that low level an optimization? – Thomas Oct 24 '17 at 08:45
  • *If* you need that high performance Java is the wrong language in the first place. – luk2302 Oct 24 '17 at 08:46
  • You're assuming that JIT doesn't compile for example `ldiv` + `lrem` into `divmod`. – Kayaman Oct 24 '17 at 08:50
  • Let me clarify: I _want to use it_ because it usually is more readable in writing out above types of algorithms. I _expect it to be there_ because it is more natural for the CPU. I will not make any assumptions as to what the JIT does or does not do, because assuming either way about compilers wil bite you. – Qqwy Oct 24 '17 at 09:04
  • Java works on a higher abstraction level. Unless you can see the intrinsic methods use some specific opcodes, you can't assume anything. However, that doesn't mean the JVM wouldn't internally use `divmod` if JIT so chooses. – Kayaman Oct 24 '17 at 09:24

2 Answers2

6

The HotSpot JIT compiler will replace division and modulo operations against the same arguments with a single divmod operation, if supported. So while this may not address the readability concerns, you don't need to worry about performance.

From the OpenJDK 9 source code:

  case Op_ModI:
    if (UseDivMod) {
      // Check if a%b and a/b both exist
      Node* d = n->find_similar(Op_DivI);
      if (d) {
        // Replace them with a fused divmod if supported
        if (Matcher::has_match_rule(Op_DivModI)) {
          DivModINode* divmod = DivModINode::make(n);
          d->subsume_by(divmod->div_proj(), this);
          n->subsume_by(divmod->mod_proj(), this);
        } else {
          // replace a%b with a-((a/b)*b)
          Node* mult = new MulINode(d, d->in(2));
          Node* sub  = new SubINode(d->in(1), mult);
          n->subsume_by(sub, this);
        }
      }
    }
    break;

By using diagnostic options to print the generated JIT instructions, I was able to see that a method that used both idiv and irem instructions at the C1 optimization level used only a single idiv instruction at the C2 level.

Miles
  • 31,360
  • 7
  • 64
  • 74
1

Java has this implemented for BigInteger or BigDecimal. These are meant for really huge integers and decimal numbers, rather than extreme efficiency.

Low level optimization is not the strength of Java, so I'd recommend opting out from Java. You can make the algorithm in C or even use Assembler. Then, if you need to use it in a Java application, you can always make it a library. Then, with Java Native Interface, you can use the library within your app.

Vlasec
  • 5,500
  • 3
  • 27
  • 30
  • In fact, the CPU power nowadays is so powerful that there is no big difference to do it in one operation or two operations. I think there would be difference up to second level if you do `divmod` for 1G times in a row. – Alex Oct 24 '17 at 08:57
  • I'm glad CPUs are powerful and applications don't have to be optimized to the last bit. But giving up on optimization is not valid for some algorithms. – Vlasec Oct 24 '17 at 09:19
  • However, in Java, you have no control over instructions used on the CPU. Java has various optimizations in the JVM, and in theory it could use the divmod instruction. But it could also run on some 8-bit processor, some ARM phone, ... and maybe some of the devices has no divmod. – Vlasec Oct 24 '17 at 09:23
  • To whoever who downvoted my answer, please come up with a better one or at least tell me what is wrong with mine. – Vlasec Sep 20 '18 at 17:18