在以下测试代码中,断言失败
NSDecimalNumber *num1 = [[NSDecimalNumber alloc] initWithInteger:1];
NSDecimalNumber *num2 = [[NSDecimalNumber alloc] initWithInteger:6];
NSDecimalNumber *num3 = [[NSDecimalNumber alloc] initWithInteger:3];
NSDecimalNumber *result1 = [num1 decimalNumberByDividingBy:num2]; // 1 ÷ 6
NSDecimalNumber *result2 = [result1 decimalNumberByMultiplyingBy:num3]; // 1 ÷ 6 x 3 = 0.5
NSDecimalNumber *num4 = [[NSDecimalNumber alloc] initWithFloat:0.5];
NSAssert([result2 compare:num4] == NSOrderedSame, @"Math error");
我知道这与浮点精度有关,1 ÷ 6 会引入这个问题。结果 2 是 0.49999999999999999999999999999999999998 而不是 0.5。
我正在尝试验证两个数学表达式是否给出相同的结果。我是否应该为此目的不使用比较,而是允许两个 NSDecimalNumbers 之间存在一些小的分数差异?或者也许我应该使用 decimalNumberByDividingBy:withBehavior: 方法并进行一些舍入?我不确定如何最好地进行。理想情况下,结果 2 是 0.5,我不需要破解比较。
编辑:这就是我在比较阶段考虑使用容差方法的方式(不理想)-
- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
if ([num compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
// Number is negative. Multiply by -1
NSDecimalNumber * negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
exponent:0
isNegative:YES];
return [num decimalNumberByMultiplyingBy:negativeOne];
} else {
return num;
}
}
- (void)test {
NSDecimalNumber *num1 = [[NSDecimalNumber alloc] initWithInteger:1];
NSDecimalNumber *num2 = [[NSDecimalNumber alloc] initWithInteger:6];
NSDecimalNumber *num3 = [[NSDecimalNumber alloc] initWithInteger:3];
NSDecimalNumber *result1 = [num1 decimalNumberByDividingBy:num2]; // 1 ÷ 6
NSDecimalNumber *result2 = [result1 decimalNumberByMultiplyingBy:num3]; // 1 ÷ 6 x 3 = 0.5
NSDecimalNumber *num4 = [[NSDecimalNumber alloc] initWithFloat:0.5];
NSDecimalNumber *tolerance = [[NSDecimalNumber alloc] initWithFloat:0.000000000001];
NSDecimalNumber *delta = [self abs:[result2 decimalNumberBySubtracting:num4]];
NSAssert([delta compare:tolerance] == NSOrderedAscending, @"Math error");
}