gpt4 book ai didi

java - 当预期等于输出时测试用例失败

转载 作者:行者123 更新时间:2023-12-02 06:04:20 26 4
gpt4 key购买 nike

在详细介绍之前,是的,这是一项家庭作业。不,我不需要答案,只是尝试这个或那个的提示和/或建议。

问题是这样介绍的:

Create a class, ExactNumber, that uses two long properties named left and right (representing the portion of the number that is to the left and right of the decimal point respectively). For example, 3.75 would be represented by new ExactNumber(3, 7500000000000000L). Note the L on the end which tells Java the large number is a long. This translates to: 3 + 7500000000000000/10000000000000000 = 3.75

这是我的代码:

public class ExactNumber {
private long left;
private long right;

public ExactNumber(long left, long right) {
this.left = left;
this.right = right;
}

public String toString() {
return String.valueOf(doubleValue());
}

public double doubleValue() {
return ((double) left + (double) (right/ 100000000000000L) / 100);
}

public int compareTo (ExactNumber exactNumber) {
if(exactNumber.left < left) {
return 1;
}
else if (exactNumber.left == left) {
if (exactNumber.right < right) {
return 1;
}
else if (exactNumber.right == right) {
return 0;
}
else {
return -1;
}
}
else {
return -1;
}
}

public boolean equal(ExactNumber thisobject) {
if (thisobject instanceof ExactNumber) {
if (thisobject.doubleValue() == this.doubleValue()) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}

public double add(ExactNumber exactNumber) {;
return ((left+exactNumber.left) + (double)((right+exactNumber.right)*1E-16));
}
}

我的问题是当预期值等于实际值时测试会出现错误。以下是测试用例(注意:还有更多测试用例,但它们通过了 JUnit 测试):

public class TestExactNumber extends TestCase {
ExactNumber threesevenfive = new ExactNumber(3, 7500000000000000L);
ExactNumber threesevenfive_andalittlebit = new ExactNumber(3, 7500000000000001L);
ExactNumber threesevenfive_dupe = new ExactNumber(3, 7500000000000000L);
ExactNumber ten = new ExactNumber(10, 0);
ExactNumber thirteensevenfive = new ExactNumber(13, 7500000000000000L);
ExactNumber sevenfifty = new ExactNumber(7, 5000000000000000L);

public void test_equals() {
assertFalse(threesevenfive.equals(threesevenfive_andalittlebit));
assertEquals(threesevenfive, threesevenfive_dupe);
}

public void test_add() {
assertEquals(threesevenfive.add(ten), thirteensevenfive);
assertEquals(threesevenfive.add(threesevenfive), sevenfifty);

上面的assertEquals在JUnit测试中失败了,但是说(例如)预期= 13.75和实际= 13.75。

非常感谢任何关于我需要如何处理我的代码的提示或提示。提前谢谢您。

注释:

  • 根据我的导师的说法,我不应该使用 doubleValue 方法来实现 equals 方法。我知道我的代码中确实有它,但那是在讲师给我提示之前,我只是不确定如何更改它。

  • 我正在使用 eclipse for java 来编写此代码。

最佳答案

您的equal方法从未被使用过。 assertEquals() 使用的 Java 方法称为 equalS(并且您必须覆盖 equals() 方法派生自对象)。因此,断言将使用从 Object 继承的 equals 方法,它将比较实际的实例,而不是使用您的 equals 方法来比较对象值。由于它们是两个不同的实例,因此它们不相等。

最后,这两个实例将使用 toString() 绘制,结果是 expected = 13.75 和actual = 13.75。(因为您的 toString() 仅返回值,忽略实例之间的差异)

<小时/>

您的导师回应:Java 中的 Long 是一个 64 位长的数字。 Java中的Double是按照IEEE754标准实现的,只留下52位尾数。含义:长数到 double 的任何转换,其中长数在位 53 到 63 上设置位 - 将导致指数以某种方式移动,从而导致 LSB 周围的精度丢失- 导致不精确的双值。

因此,比较 double 值以确定相等性不足以满足您所需的“精确数字”设计。

示例:

Long bigLong = 1L<<51; //picked 51: 52 and 53 already causing rounding issues.
Long long1 = bigLong + 1L;
Long long2 = bigLong + 2L;
System.out.println(long1+" -> " + long1.doubleValue());
System.out.println(long2+" -> " + long2.doubleValue());

//false, enough precision to preserve bit "0" and "1".
System.out.println(long1.doubleValue()==long2.doubleValue());

输出:

2251799813685262 -> 2.251799813685262E15
2251799813685263 -> 2.251799813685263E15
false

设置位 54 时:

Long bigLong = 1L<<54;
Long long1 = bigLong + 1L;
Long long2 = bigLong + 2L;
System.out.println(long1+" -> " + long1.doubleValue());
System.out.println(long2+" -> " + long2.doubleValue());
System.out.println(long1.doubleValue()==long2.doubleValue());

输出:

18014398509481985 -> 1.8014398509481984E16
18014398509481986 -> 1.8014398509481984E16
true

请注意,指数从 15 增加到 16,这将消除两个长整数之间的“1”差异。

要解决此问题,您可以将 left1left2 以及 right1right2 进行比较,而无需将其转换为双倍。

关于java - 当预期等于输出时测试用例失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22412564/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com