0

I have

x /= y;

Where x & y are both double

I would like x to be the integer part of x/y , how do I do this?

I have tried

x /= y;
x = x.intValue();

But am receiving a double cannot be dereferenced error in TIO which I presume means the double x does not have that method

IO x = x\y: Carry out float division then round towards -∞

Sample table

NB all I'm after is to change this code to add in floor division with \

Greedo
  • 4,967
  • 2
  • 30
  • 78
  • Just cast it to int but be careful that you might get 1 less than you expect. For example, `x = 10.0 / 3.333333... (recurring); x = (int) x;` then you might get 2 instead of 3. – DodgyCodeException Dec 11 '17 at 11:40
  • Try `x = (int)x/(int)y;`. Also `double` is a primitive type, so you can't call methods on them. You probably meant to use the wrapper class `Double`. – QBrute Dec 11 '17 at 11:40
  • Possible duplicate of https://stackoverflow.com/questions/3144610/integer-division-how-do-you-produce-a-double – vinS Dec 11 '17 at 11:42
  • 1
    Can you add some input/output. Based on when you want to use an integer, the result could be different. What decimal part do you want to loose ? – AxelH Dec 11 '17 at 11:47
  • 1
    It's probably a bad idea to have an "integer division" operator for double arguments. I can't remember a language where that was done. The idea is to either cast the arguments or the result, to get what you really want. - For instance, what do you expect if you write `1\0.5`? – laune Dec 11 '17 at 12:01
  • @AxelH Added IO, I want to round down (including with negatives), Ideally I'd like 1\0.333... to give 3 not 2 – Greedo Dec 11 '17 at 12:27
  • 1
    You got the names of x and y wrong. x is the numerator and y is the denominator. – DodgyCodeException Dec 11 '17 at 12:42
  • 1
    My english might be wrong, but isn't it suppose to be `y / x` here ? `numerator / denomintaor` ? – AxelH Dec 11 '17 at 12:42

3 Answers3

4

Force integer division on a double?

To force integer division, use int or long (for the calculation part); long would probably be the better choice:

x = (double)((long)x / (long)y);

That uses an explicit cast back to double for emphasis; you can just write it with the implicit cast back to double if you prefer:

x = (long)x / (long)y;

Do note that (long)y on a non-zero y can result in 0 (for instance, if y is 0.3), which then ends up being division-by-zero and thus a runtime exception.

I would like x to be the integer part of x/y

That's a different question than the title; that's not integer division, that's getting the integer part of the result of floating point division. If that's what you want, just cast the result:

x = (long)(x / y);

...(and of course the long is then implicitly cast back to double) or use Math.floor on it.


I have tried

x /= y;
x = x.intValue();

But am receiving a double cannot be dereferenced error

Right. x is a double, not Double. Primitives (like double) don't have methods, only reference types (like Double) do.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    Introduces the possibility of an Arithmetic exception (/ by zero), much more than in the original code - don't use `/(int) y`. – laune Dec 11 '17 at 11:48
  • @AxelH: No, that would still be floating-point division. `x` would be first narrowed to `int` (by the cast), but then widened again for the division: https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2 – T.J. Crowder Dec 11 '17 at 11:52
  • @laune: The OP asked for integer division. It's true that if `(int)y` is `0` it will throw an exception, and I'll flag it, but that's not really part of the question. – T.J. Crowder Dec 11 '17 at 11:53
  • @AxelH: No, the result in `x` might well not be an integer in your example, because (again) it would be floating point division, not integer division. – T.J. Crowder Dec 11 '17 at 11:55
  • Then his title needs editing, because in the Q we have explicitly: "I would like x to be the integer part of x/y", and that's not the same as integer division. – laune Dec 11 '17 at 11:56
  • @laune: LOL I literally just added that observation to the answer! Great minds. – T.J. Crowder Dec 11 '17 at 11:58
  • 2
    OK! I'm still not quite satisfied with your solution because it uses int. Why not use long? – laune Dec 11 '17 at 12:41
  • @laune: LOL No good reason. :-) The OP said "integer" in the title and tried to use `intValue`, so my mind went `int`, but you're absolutely right, `long` would be a better choice (and still qualifies as "integer division"). – T.J. Crowder Dec 11 '17 at 12:50
  • 1
    Hehe: "integer" according to the dictionary isn't always "int.*" according to some language spec. The number of programmers that are always aware of this distinction can be counted using a short. ;-) – laune Dec 11 '17 at 13:02
  • @laune: A `byte` even. :-) – T.J. Crowder Dec 11 '17 at 13:12
  • The JLS often uses the term ["inegral type"](https://docs.oracle.com/javase/specs/jls/se9/html/jls-4.html#jls-4.2.1) to distinguish this from int (although it also uses "integer" for the same purpose). – DodgyCodeException Dec 11 '17 at 13:31
  • 1
    @DodgyCodeException The JLS reader is well advised to look up the definition of "integral types": it includes char. - Does the JLS really contain "integer type(s)" somewhere? – laune Dec 11 '17 at 14:22
  • @laune examples: Section 4.2.2 "Integer Operations". Section 4.2.1 "The values of the integral types are integers in the following ranges". – DodgyCodeException Dec 11 '17 at 14:37
  • @DodgyCodeException I've seen these, but I think that "integer operations" just refers to the algebraic operations of integer numbers, whereas in "values ... are integers" the "integers" was intended to mean "the subsets of the integer numbers". - Sadly, the JLS is lacking a section "glossary", but the places where some term is defined are rather evident. – laune Dec 11 '17 at 17:27
4
x = java.lang.Math.floor(x/y);

Relying on some Math function is arguably the best choice. "Returns the largest (closest to positive infinity) double value that is less than or equal to the argument and is equal to a mathematical integer."

If you need the symmetric version (truncation towards zero), you'll have to handle negative quotients:

 floor(abs(x/y))*signum(x/y)
laune
  • 31,114
  • 3
  • 29
  • 42
3

If a smaller data type is assigned to a bigger data type, there'll be no error. But the assignment of bigger to smaller gives error. In this case, you need to make compatible these data types with each other using type conversion ('x = (Type) y'). Converting a double to int is an example of assigning a bigger data type (double) to smaller (int). When we perform this operation, the double variable lost its precision and its "integer part" is assigned to the int variable.

double x = 3, y = 2;
x /= y;
int integerPart = (int) x;
System.out.println(integerPart); // Prints 1

From small to big, the numeric data types are as follows btw:

byte < short < int < long < float < double

Edit: After your last edit I realized what you actually ask. Your first expression was wrong. You don't want to find integer part of the double result of division, you want its floor. Just use java.lang.Math.floor:

double[] x = {-10, -7, 1, 3, 7.1, 9.5};
double[] y = {-10, -7, -1.7, 0.5, 7.1, 9.5};
for (int i = 0; i < y.length; i++) {
  for (int j = 0; j < x.length; j++)
    System.out.print(Math.floor(x[j] / y[i]) + " ");
    System.out.println();
}
Dorukhan Arslan
  • 2,676
  • 2
  • 24
  • 42
  • I prefer that version, especially when one performs the division in a loop. Using double for the better precision and then cast the result. – Tom Dec 11 '17 at 11:43
  • So why not use long? – laune Dec 11 '17 at 12:02
  • 1
    The comparison of types given above can be misleading. All int values can be represented precisely (without any loss) in a double variable, but not in a float. Similarly, not all long values can be represented precisely by a double. – DodgyCodeException Dec 11 '17 at 12:07
  • Just to give an example to illustrate my above comment: `long i = 0x0123456789abcdefL; double d = (double) i; long j = (long) d; assert(i != j);`. So your first sentence, "If a smaller data type is assigned to a bigger data type, everything is okay" is *not* okay. – DodgyCodeException Dec 11 '17 at 14:00
  • I don't mean literally "everything" there. I mean we can convert types in that case without an error. Nonetheless, your reminder is nice. Thanks. It's edited. – Dorukhan Arslan Dec 11 '17 at 14:05