Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 分母是负数_Java_Junit_Fractions_Greatest Common Divisor - Fatal编程技术网

Java 分母是负数

Java 分母是负数,java,junit,fractions,greatest-common-divisor,Java,Junit,Fractions,Greatest Common Divisor,我编写了一个添加两个分数的程序,如果分母是0,它应该抛出IllegalArgumentException。当我测试它时,我得到一个失败,当我尝试添加0/2+-1/2时,我应该得到-1/2,但是我得到1/-2,我如何解决这个问题 语言是德语,bruch表示分数,neuenner表示新分母,neuZaehler表示新分子,ggt是gcd 我删除了 assertEquals("Zaehler = -1 Nenner = 2", rechnen.Rechnen.bruch

我编写了一个添加两个分数的程序,如果分母是0,它应该抛出
IllegalArgumentException
。当我测试它时,我得到一个失败,当我尝试添加
0/2+-1/2
时,我应该得到
-1/2
,但是我得到
1/-2
,我如何解决这个问题

语言是德语,
bruch
表示
分数
neuenner
表示
新分母
neuZaehler
表示
新分子
ggt
gcd

我删除了

assertEquals("Zaehler = -1 Nenner = 2",
                rechnen.Rechnen.bruchAddition(0, 2, -1, 2));
但是我得到了这个错误
java.lang.AssertionError

这是我的代码:

    public class Rechnen {

    public static String bruchAddition(int z1, int n1, int z2, int n2) {

        int neuZaehler = (z1 * n2) + (z2 * n1);
        int neuNenner = n1 * n2;

        int ggt = ggt(neuZaehler, neuNenner);
        neuZaehler = neuZaehler / ggt;
        neuNenner = neuNenner / ggt;

        if (n1 == 0 || n2 == 0) {
            throw new IllegalArgumentException();
        }
        return ("Zaehler = " + neuZaehler + " Nenner = " + neuNenner);

    }

    static public int ggt(int x, int y) {
        if (y == 0) {
            return x;
        }
        return ggt(y, x % y);
    }
}
这是JUnit测试用例:

import static org.junit.Assert.*;
import org.junit.Test;
public class RechnenTest {
    @Test
    public void test() {
        assertEquals("Zaehler = 1 Nenner = 1",
                rechnen.Rechnen.bruchAddition(1, 3, 2, 3));
        assertEquals("Zaehler = 1 Nenner = 1",
                rechnen.Rechnen.bruchAddition(5, 8, 3, 8));
        assertEquals("Zaehler = 1 Nenner = 1",
                rechnen.Rechnen.bruchAddition(10, 16, 3, 8));
        assertEquals("Zaehler = 1 Nenner = 3",
                rechnen.Rechnen.bruchAddition(-1, 3, 2, 3));
        assertEquals("Zaehler = -1 Nenner = 2",
                rechnen.Rechnen.bruchAddition(0, 2, -1, 2));
        assertEquals("Zaehler = -2 Nenner = 3",
                rechnen.Rechnen.bruchAddition(-1, 3, 1, -3));
        try {
            rechnen.Rechnen.bruchAddition(1, 1, 1, 0);
            fail();
        } catch (IllegalArgumentException e) {
            assertTrue(true);
        }
        try {
            rechnen.Rechnen.bruchAddition(Integer.MAX_VALUE, 1, 1, 1);
            fail();
        } catch (IllegalArgumentException e) {
            assertTrue(true);
        }
        assertEquals("Zaehler = 1 Nenner = " + Integer.MAX_VALUE,
                rechnen.Rechnen.bruchAddition(0, Integer.MAX_VALUE, 1,
                        Integer.MAX_VALUE));
    }
}

操作后,检查分子和分母上的符号。如果它们都是负数,或者分子是正数,分母是负数,则翻转两个符号。

我不确定欧几里德的GCD算法(
ggt
)是否适用于负数。我想你可能希望ggt的结果总是积极的。最好确保只使用正整数调用
ggt
(分子为0):

在Java中,如果
x
是负数,而
y
是正数,
x%y
将是负数,我认为这就是为什么会得到负面结果的原因

编辑:回答第二个问题(为什么会得到一个
AssertionError
):问题是您的数据溢出了。将分母为Integer.MAX_VALUE的两个分数相加,算法将这两个值相乘,得到
neuenner
。当然,这将产生一个大于Integer.MAX_值的结果,因此
neuninner
将具有不正确的值,从而将一切搞乱。可能的解决方案:(1)在
bruchAddition
ggt
中使用
long
值;(2) 使用
biginger
,可以处理任意大小的整数;(3) 不要使用Integer.MAX\u值进行测试(改用Short.MAX\u值);(4) 更改
bruchAddition
以处理
n1==n2
的特殊情况(然后您可以添加分子),或者
n1
可被
n2
整除,反之亦然(然后可以将分子乘以
n1/n2
n2/n1
,这样可以避免处理大于
n1
n2
的数字)

编辑2:进一步澄清解决方案(1):仅将声明从
int
更改为
long
是行不通的,如下所示:

public static String bruchAddition(int z1, int n1, int z2, int n2) {

    long neuZaehler = (z1 * n2) + (z2 * n1);
    long neuNenner = n1 * n2;
因为乘法仍然是使用
int
s完成的,并且在将值转换为
long
之前仍然会溢出。但是,我已经测试了这一点,它可以工作:

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;

确保所有的计算都是使用较大的整数进行的。同时将
ggt
方法的结果类型和参数类型更改为
long
,并将
ggt
变量更改为
long
,但不需要进行任何其他转换。

我使用了调试器,并注意到了标记,正如您所说的y flip!所以我使用了
int ggt=ggt(Math.abs(neuZaehler),neuenner);
解决了这个问题。但是我在
rechnettest
JUnit测试用例中得到了这个
java.lang.AssertionError
,我不知道如何解决它!它成功了!我把代码改成了
int ggt=ggt(Math.abs(neuZaehler),neuenner)
它成功了。但是我仍然在JUnit测试用例中遇到了
java.lang.AssertionError
错误。如何解决它呢?很抱歉打扰你,我只是一个编程乞丐,我试过使用这4种解决方案,但都不起作用,可能是我做错了什么。你试过其中一种解决方案吗?@Maged是的,我试过ed#1,但我意识到一些额外的解释可能有用。请参阅我的第二次编辑。
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;