I'm not sure Euclid's algorithm for GCD (ggt
) works well with negative numbers. I think you may want the result of ggt
to be positive always. It's probably best to make sure ggt
is only called with positive integers (or 0 for the numerator):
int ggt = ggt(Math.abs(neuZaehler), Math.abs(neuNenner));
In Java, if x
is negative and y
is positive, x % y
will be negative, which I think is why you're getting the negative results you're getting.
EDIT: To answer the second question (why you're getting an AssertionError
): The problem is that you're overflowing. You're adding two fractions whose denominator is Integer.MAX_VALUE, and your algorithm multiplies the two values to get neuNenner
. Of course, this will produce a result greater than Integer.MAX_VALUE, and so neuNenner
will have the incorrect value, messing everything up. Possible solutions: (1) use long
values inside bruchAddition
and ggt
; (2) use BigInteger
, which will let you handle integers of any size; (3) don't test with Integer.MAX_VALUE (try Short.MAX_VALUE instead); (4) change bruchAddition
to handle special cases where n1 == n2
(you can then just add the numerators), or n1
is divisible by n2
or vice versa (you can then multiply a numerator by n1/n2
or n2/n1
which would avoid handling numbers larger than n1
or n2
).
EDIT 2: To further clarify solution (1): it won't work just to change the declarations from int
to long
like this:
public static String bruchAddition(int z1, int n1, int z2, int n2) {
long neuZaehler = (z1 * n2) + (z2 * n1);
long neuNenner = n1 * n2;
because the multiplications are still done using int
s, and will still overflow, before the value is casted to a long
. However, I've tested this and it works:
public static String bruchAddition(int z1, int n1, int z2, int n2) {
long neuZaehler = ((long)z1 * (long)n2) + ((long)z2 * (long)n1);
long neuNenner = (long)n1 * (long)n2;
to make sure all the computations are done using the larger integer size. Also change the result type and parameters types of the ggt
method to long
, and change the ggt
variable to long
, but you don't need to do any other casting.