Win a copy of Fixing your Scrum this week in the Agile forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Rob Spoor
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Holloway
  • Piet Souris
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Himai Minh

Operator

 
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Everyone,
I have recently started learning java and I am facing issue with this question.

class test{

public static void main(String [] args){
int x = 1 + 1 / 2*3;
System.out.println(x);
}
}

I am not able to understand how it gives the output as 1. Because according to bodmas the output is 2.5 and as the data type is of integer, so after rounding it off, it should either give 2 or 3
Please help me with this.  
 
Saloon Keeper
Posts: 8434
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In order to pick this apart there's two things you need to know: "precedence of operators", and the fact that integer divides only give whole number (truncated) results.

For precedence, it's as though it had been written as:
1 + ((1 / 2) * 3)

Where 1/2 is performed first, and 2 goes into 1 zero times.
 
sahil Kairon
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you so much for the explanation, it really helped me in understanding this.
 
Marshal
Posts: 73738
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

To add to what Carey said, there are four considerations,
  • 1: the left to right rule,
  • 2: the precedences of the operators,
  • 3: the direction the operators associate in, and
  • 4: the rounding mode used.
  • The left to right rule means a subexpression on the right is not evaluated until whatever is to its left has been evaluated, but allowing for precedences. That doesn't affect the present expression.
    Precedences means that * and / are evaluated with the same precedence, which is higher than +.
    Most operators associate to the left, which means they behave as if the left one of two operators with the same precedence were evaluated first. That is why Carey wrote (...) round the division rather than the multiplication. The = operator associates to the right.
    Integer arithmetic has used “round towards zero” for as long as I can remember; as Carey said, 1 / 2 rounds towards zero and will therefore evaluate to 0. It is rounding that is the real explanation here, as Carey said.
     
    Master Rancher
    Posts: 1005
    27
    Eclipse IDE Postgres Database C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:...
    Integer arithmetic has used “round towards zero” for as long as I can remember; as Carey said, 1 / 2 rounds towards zero and will therefore evaluate to 0. It is rounding that is the real explanation here, as Carey said.



    The OP was asking about Java so your answer is 100.00% correct.
    I am still considering that my next gig might be in the very popular language Python, so I will mention that countless millions would expect what we see here following.
    I mentioned that they should put it in as one line in the Python tutorials, because people coming from C/C++/Java/C#/etc. etc. etc. "know" that it behaves as you said.
    It caused a big fight over whether it belongs in the intro section of the tutorials or only where they explain integer division operator more fully, not sure where that one went:

    PS F:\Labs> py
    Python 3.9.5 (tags/v3.9.5:0a7dcbd, May  3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> -3 // 2
    -2


    NOT TOWARDS ZERO, Python decided to "fix" both modulo arithmetic and integer division to behave "more rationally" than in C/C++/C#/Java and friends.
     
    Campbell Ritchie
    Marshal
    Posts: 73738
    332
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    My former supervisor was on the Forth standards committee, and about twelve years ago, Forth was standardised to change from round down to round towards zero.Of course, most Forth implementations have a /MOD operator which leaves both the quotient and the remainder on the stack.
     
    Jesse Silverman
    Master Rancher
    Posts: 1005
    27
    Eclipse IDE Postgres Database C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:My former supervisor was on the Forth standards committee, and about twelve years ago, Forth was standardised to change from round down to round towards zero.



    Wow, that is a big change!!  EDIT--I see that what you show as "New Forth Behavior" is the same as Java/C/C++/C#, but the "Old Forth Behavior" wasn't the same as Python 3.  Python 3 has the excuse/rationale, that for all integers m, n: m % n is between 0 inclusive and n exclusive.  So the sign of the result of all modulo operations always matches the sign of n.  Together with the round down on integer division, it means that (m / n) * n + m % n == m for all m, n ... (it is late, I hope I typed that right...bedtime here.)

    It makes me wonder if it caused a Rift in the Forth community like the vicious Python 2 vs. Python 3 Rift that raged acrimoniously for near a decade.

    I suspect not, because Forth programmers are so individualistic as to make cats look like Herd Animals, and the snarky part of me wonders whether there were enough Forth people around for the world to notice a rift if one did occur.

    I can't believe how often I forget Forth when I list all extant programming languages in my head (everyone does that while they are waiting for a "Walk" signal or waiting on line, of course, right?)...In particular Dragon 4 x Forth was rather popular on the Atari ST when I was a kid, and tho he was admittedly quite weird, I had a friend in Engineering School who had Forth as their favorite language well above FORTRAN, Pascal or C....

    I truly doubt Python will go back on the mod and integer division change again tho.  It is now consistent and nice except that it disagrees with the rest of the computing world.
     
    Campbell Ritchie
    Marshal
    Posts: 73738
    332
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Jesse Silverman wrote:. . . (m / n) * n + m % n == m for all m, n . . .

    That is called “Euclidean” behaviour. I thought that is the same as Java®'s behaviour.
    I don't remember a rift amongst Forth developers, but I certainly remember a rift amongst Eiffel programmers when ECMA367 came out, and Eiffel dropped below the radar. It seems to have reappeared on Tiobe.
     
    Marshal
    Posts: 8050
    569
    Mac OS X VI Editor BSD Linux
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    @OP

    When you post the code, please use code tags.

    Doesn't it look better?

    Note: I have also fixed few indentation and formatting issues. Now you see more discipline in the code, and that's what you supposed to be aiming for moving forward.
     
    Jesse Silverman
    Master Rancher
    Posts: 1005
    27
    Eclipse IDE Postgres Database C++ Java
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:

    Jesse Silverman wrote:. . . (m / n) * n + m % n == m for all m, n . . .

    That is called “Euclidean” behaviour. I thought that is the same as Java®'s behaviour.
    I don't remember a rift amongst Forth developers, but I certainly remember a rift amongst Eiffel programmers when ECMA367 came out, and Eiffel dropped below the radar. It seems to have reappeared on Tiobe.



    So if Java's behavior is Euclidean, maybe Python 3's behavior is a combination of Euclidean behavior plus m % n must be between 0 (inclusive) and n (exclusive).
    Java/C/C++/C# doesn't ensure that, because you can get a negative result when n is positive if m is negative.

    All the OP needed to remember here tho is when m / n means integer division, which is whenever neither is float or double, and that in Java, integer division always goes towards 0.

    However, for anyone jumping back and forth between Python and Java, as I have been, it is important to remember the differences, and Python does three "Weird But Sensible" things compared to Java and the other normal guys:
    / always means floating point division, regardless of operand type, if you want integer division, which they call floor division you must use the // operator, which means floor division rather than end of line comment.
    floor division always goes towards negative infinity
    m % n always gets the same sign as n (unless the result is 0), rather than Java always giving a result with the sign of m

    Java's mod operator works like C/C++/C#:
    jshell> -5 % 2
    $1 ==> -1

    jshell> -5 % -2
    $2 ==> -1

    jshell> 5 % 2
    $3 ==> 1

    jshell> 5 % -2
    $4 ==> 1


    Lastly, do integer division and modulus arithmetic behavior belong in Beginning Java?

    Some programmers go ages without using them, but they are rampant in computer science, so from that angle, I would say "Yes", as much as pow(), exp(), floor(), ceil() and friends, and mostly used by the same crowd.

    Whoa, not lastly, because this thread made me take the first look at Math's javadocs in a very long time, because I stupidly thought "I already knew what was there."  Boy was I wrong!!
    Let's say your boss has you "directly translating some Python code that depends on weird Python floor division and modulus behavior".

    Are you stuck writing weird, awkward code?

    When I first saw this thread I thought "Yeah, too bad."  Because when I first learned the Math class it was pretty skimpy.

    But noooo....when you actually WANT to mimic Python 3 behavior, the enhanced java.lang.Math gives you:
    static int floorDiv​(int x, int y)
    Returns the largest (closest to positive infinity) int value that is less than or equal to the algebraic quotient.
    static long floorDiv​(long x, int y)
    static long floorDiv​(long x, long y)

    Returns the largest (closest to positive infinity) long value that is less than or equal to the algebraic quotient.

    static int floorMod​(int x, int y)
    Returns the floor modulus of the int arguments.
    static int floorMod​(long x, int y)
    Returns the floor modulus of the long and int arguments.
    static long floorMod​(long x, long y)
    Returns the floor modulus of the long arguments.

    The descriptions are very math-y, but I checked in JShell and they seem to behave a la Python 3 and its "New Modulus Math".

    You need to ask for them by name, and you can't directly compute them without casting for float/double, but there they are!
    There are some extremely useful things in Math I'd missed out on since Java 5, 6, 8 and 9 in addition to these!

    In my defense, I often worked with people who looked down on Java as about as up-to-date as "Laverne and Shirley" re-runs, who completely ignored the hard work being done to add stuff it used to lack.
    I'm still embarrassed, I might have--would have--written complex, tricky custom code that would be totally unnecessary if I was doing a straight translation of some related Python code to Java!

    The difference is that the Java folks absolutely refuse to break your Old Code by changing prior Guaranteed Behavior.
    To falsely conclude as a result that Java isn't giving you new ways to do things in those Same Old Classes is something this thread helped me get further away from.
    Your old Java 1.4 code, with few exceptions, will continue to work now in Java 16, and give the same results.
    That doesn't necessarily mean that is how you should still be writing it...maybe obvious to people here, but I quite regularly hear/read people dismissing Java for reasons that haven't been true for quite a long time.

    Cool.
     
    Campbell Ritchie
    Marshal
    Posts: 73738
    332
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    The JLS mandates that behaviour:-

    The remainder operation for operands that are integers after binary numeric promotion (§5.6) produces a result value such that (a/b)*b+(a%b) is equal to a.

    The sign of i % j is always the same as the sign of i (except when the remainder is 0).
    Floor dividon suggests to me that it uses floor rounding, in which case −3 // 2 should come out to −2.

    . . . do integer division and modulus arithmetic behavior belong in Beginning Java?

    Yes.

    Java as about as up-to-date as "Laverne and Shirley" re-runs . . .

    It certainly was before Java8.

    . . . people dismissing Java for reasons that haven't been true for quite a long time.

    That has always happened. Java1.0 might have been slow, but I am sure there are still people who remember that and think all Java® implementations are slow.
     
    If you are using a wood chipper, you are doing it wrong. Even on this tiny ad:
    the value of filler advertising in 2021
    https://coderanch.com/t/730886/filler-advertising
    reply
      Bookmark Topic Watch Topic
    • New Topic