【问题标题】:division by zero in objectiveC在目标 C 中除以零
【发布时间】:2015-04-15 08:29:07
【问题描述】:

为什么下面的代码在运行时不会抛出算术错误 -> 1/0;

printf("in start\n");
int i=1/0;
//int o=i;
NSString* myString = [@(i) stringValue];
printf("%s", [myString UTF8String]);
printf("\nafter start\n");

控制台:

in start
-1074745488
after start

【问题讨论】:

  • 如果您想要异常,只需尝试使用浮点数或双精度数即可。
  • 好的。感谢您的提示。
  • 除了 NSString(您只能作为 c 字符串访问)之外,这个问题没有具体的 Objective-c。

标签: objective-c


【解决方案1】:

为什么要这样做?

XCode 给你警告Division by zero is undefined。这对你来说应该是一个足够大的标志了。


注意:

C# doesn't always throw an exception.

C++ send a signal, which if not handled, just kills your process.


C++ 线程中有一个惊人的解释:

除以零是一个逻辑错误,是程序员的错误。你 不应该试图应对它,你应该调试并消除它。

修复墙上的洞,而不是试图在上面挂一张照片。

【讨论】:

  • 为什么不应该呢?我知道的每一种语言都可以。我当然在 XCode 中看到了警告,但我的问题是它为什么不抛出错误。显然它不会而且只会给出任何随机数,这可能会非常令人困惑。
  • 如果除数在运行时未知,因为它是从任何输入读取的,编译器不会发出警告。
  • 这就是为什么添加 if (value != 0) 的原因,这比捕获异常更容易且资源消耗更少。
  • 这取决于用例。开发人员可能出于某些原因更喜欢应用程序因输入无效而崩溃。例如在测试环境中。
  • 你只是用这2个cmets自相矛盾...你想被警告阻止它还是你想让程序崩溃?
【解决方案2】:

它不会抛出错误,因为它是纯 C 语言——而且 C 不知道如何抛出错误。


如果你像进入Objective-C的客观世界

NSDecimalNumber *i = [NSDecimalNumber decimalNumberWithDecimal:[@(1) decimalValue]];
NSDecimalNumber *o = [NSDecimalNumber decimalNumberWithDecimal:[@(0) decimalValue]];

NSDecimalNumber *x = [i decimalNumberByDividingBy:o];

你会看到

*** Terminating app due to uncaught exception 'NSDecimalNumberDivideByZeroException', reason: 'NSDecimalNumber divide by zero exception'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff870cf50c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff8abd076e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff870cf3bd +[NSException raise:format:] + 205
    3   Foundation                          0x00007fff8a476ec5 -[NSDecimalNumberHandler exceptionDuringOperation:error:leftOperand:rightOperand:] + 242
    4   Foundation                          0x00007fff8a475cab _checkErrorAndRound + 57
    5   Foundation                          0x00007fff8a47606c -[NSDecimalNumber decimalNumberByDividingBy:withBehavior:] + 159
    6   devisonByZero                       0x0000000100000e54 main + 484
    7   libdyld.dylib                       0x00007fff8aaa45c9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

但你实际上可以决定,会发生什么:

NSDecimalNumberHandler *h = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                                                   scale:1
                                                                        raiseOnExactness:NO
                                                                         raiseOnOverflow:NO
                                                                        raiseOnUnderflow:NO
                                                                     raiseOnDivideByZero:NO];

NSDecimalNumber *x = [i decimalNumberByDividingBy:o withBehavior:h];

x 现在将是 NaN


但苹果也提供了可以识别计算错误的 C 类型:NSDecimal

NSDecimal one = [@1 decimalValue];
NSDecimal zero = [@0 decimalValue];
NSDecimal result;
NSCalculationError error = NSDecimalDivide(&result, &one, &zero, NSRoundPlain);
switch (error) {
    case NSCalculationNoError:
        NSLog(@"result: %@", [NSDecimalNumber decimalNumberWithDecimal:result]);
        break;
    case NSCalculationDivideByZero:
        NSLog(@"division by 0");
        break;
    default:
        NSLog(@"some calculation error");
        break;
}

【讨论】:

  • 非常感谢这个很棒的答案。这让我对此有了更好的理解和更好的看法。
猜你喜欢
  • 2012-10-18
  • 1970-01-01
  • 1970-01-01
  • 2016-07-13
  • 2012-03-10
  • 2021-08-03
  • 2011-06-12
  • 1970-01-01
  • 2010-10-16
相关资源
最近更新 更多