【问题标题】:STAssertEquals fails even though a1 = a2即使 a1 = a2 STAssertEquals 也会失败
【发布时间】:2013-06-12 08:59:55
【问题描述】:

我是单元测试的新手,我决定编写一个简单的计算器来研究这些概念,但我遇到了一个对我来说毫无意义的问题。 STAssertEquals 因 2 个显然相同的双精度值而失败。 我得到的错误是这个: “-2.89”应该等于“-2.89”:

执行计算的代码是:

- (double)calculateOperation:(int)operation numberA:(double)numA numberB:(double)numB
{
    double result = 0;

    switch(operation)
    {
        case addition:
            result = numA + numB;
            break;

        case subtraction:
            result = numA - numB;
            break;

        case multiplication:
            result = numA * numB;

        default:
            break;
    }

    return result;
}

测试是

- (void)testSubtraction
{
    //Two double positive values
    double test1 = [calculator calculateOperation:subtraction numberA:4.45 numberB:7.34];

    STAssertEquals(test1, -2.89, nil);
}

我尝试了不同的值,但似乎只有特定范围的值会导致 STAssertEquals 失败。

但是,如果我执行 STAssertEquals((4.45 - 7.34), -2.89, nil) 它可以正常工作。

我真的不知道怎么了。

【问题讨论】:

  • 尝试在你的断言中将 -2.89 转换为 double... (double)-2.89。
  • 使用NSLog()记录test1
  • 可能是浮点精度问题?
  • 我尝试使用 (double)-2.89,但没有成功。我尝试将结果与 NSLog() 打印的数字进行比较,即 -2.890000,但它也不起作用。我知道双精度和浮点类型存在一些点精度问题;但如果是这种情况,返回值不应该略有不同吗?像 -2.89000001 还是类似的?
  • Pedantry:减法只有一个s,而且在开头。

标签: objective-c unit-testing


【解决方案1】:

考虑以下设置:

double a = 4.45;
double b = 7.34;
double result = a - b;
double testVal = -2.89;

此时,如果您查看内存中 resulttestVal 的实际值,您将看到以下内容:

(lldb) p/x *(uint64_t*)&testVal
(uint64_t) $1 = 0xc0071eb851eb851f
(lldb) p/x *(uint64_t*)&result
(uint64_t) $2 = 0xc0071eb851eb851e

所以你可以看到,result 的有效数字的最后一位与我们放入 @ 的文字确实存在差异,这可能是由于减法运算中的舍入所致987654326@。当格式化代码将本机二进制表示转换为十进制时,这种差异可能并不明显,因为这些转换并不总是准确的,但它仍然会影响这两个值的文字相等性。

实际上,您可能希望在此处使用STAssertEqualsWithAccuracy,为您的应用程序选择一些适合的精度值。 (对于图形工作,我通常使用 1e-6,但您的里程可能会有所不同。)此外,由于所有内容都是 double,因此您不需要在这里显式转换。编译器将没有后缀的十进制数字文字解释为double(如果您想要float,请在十进制数字文字后面加上F,如果您想要long double,请在后面加上L。即 - 2.89F 或 -2.89L)

值得重申:尽管许多人喜欢在十进制参考框架中考虑浮点数(因为这是我们大多数人学习算术的方式),但这不是它们的存储方式,而不是“它们的工作方式”。如果您不期望它们表现得像以 10 为底的数字,那么您的失望就会少得多。这是一个典型的例子。

【讨论】:

  • 谢谢!你的解释很清楚,你指出了我没有直接问但与我遇到的问题有关的事情。我会给你 +1,但我的声誉低于 15 岁。
猜你喜欢
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 1970-01-01
  • 2018-12-17
  • 2020-09-16
  • 2015-06-25
相关资源
最近更新 更多