Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple division in Java - is this a bug or a feature?

Tags:

java

division

I'm trying this simple calculation in a Java application:

System.out.println("b=" + (1 - 7 / 10));

Obviously I expect the output to be b=0.3, but I actually get b=1 instead.

What?! Why does this happen?

If I write:

System.out.println("b=" + (1 - 0.7));

I get the right result, which is b=0.3.

What's going wrong here?

like image 824
rasgo Avatar asked May 26 '10 00:05

rasgo


3 Answers

You're using integer division.

Try 7.0/10 instead.

like image 62
Xavier Ho Avatar answered Sep 21 '22 10:09

Xavier Ho


You've used integers in the expression 7/10, and integer 7 divided by integer 10 is zero.

What you're expecting is floating point division. Any of the following would evaluate the way you expected:

7.0 / 10 7 / 10.0 7.0 / 10.0 7 / (double) 10 
like image 29
JustJeff Avatar answered Sep 23 '22 10:09

JustJeff


Please do not take this as an answer to the question. It is not, but an advice related to exploiting the difference of int and float. I would have put this under a comment except that the answer box allows me to format this comment.

This feature has been used in every respectable programming language since the days of fortran (or earlier) - I must confess I was once a Fortran and Cobol punch card programmer.

As an example, integer division of 10/3 yields integer value 3 since an integer has no facility to hold fractional residual .3333.. .

One of the ways we (old time ancient programmers) had been using this feature is loop control.

Let's say we wish to print an array of 1000 strings, but we wish to insert a line break after every 15th string, to insert some prettyfying chars at the end of the line and at the beginning of the next line. We exploit this, given that integer k is the position of a string in that array.

int(k/15)*15 == k

is true only when k is divisible by 15, an occurrence at a frequency of every 15th cell. Which is akin to what my friend said about his grandfather's dead watch being accurate twice a day.

int(1/15) = 0 -> int(1/15)*15 = 0
int(2/15) = 0 -> int(2/15)*15 = 0
...
int(14/15) = 0 -> int(14/15)*15 = 0
int(15/15) = 1 -> int(15/15)*15 = 15

int(16/15) = 1 -> int(16/15)*15 = 15
int(17/15) = 1 -> int(17/15)*15 = 15
...
int(29/15) = 1 -> int(29/15)*15 = 15
int(30/15) = 2 -> int(30/15)*15 = 30

Therefore, the loop,

leftPrettyfy();
for(int k=0; k<sa.length; k++){
  print(sa[k]);
  int z = k + 1;
  if ((z/15)*15 == z){
    rightPrettyfy();
    leftPrettyfy();
  }
}

By varying k in a fanciful way in the loop, we could print a triangular printout

1
2  3
4  5  6
7  8  9  10
11 12 13 14 15

That is to demonstrate that, if you consider this a bug, this "bug" is a useful feature that we would not want to be removed from any of the various languages that we have used thus far.

like image 40
Blessed Geek Avatar answered Sep 20 '22 10:09

Blessed Geek