Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

division by zero in objectiveC

Tags:

objective-c

why does following code do not throw an arithmetic error at runtime -> 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");

Console:

in start
-1074745488
after start
like image 702
mcfly soft Avatar asked Feb 14 '15 09:02

mcfly soft


Video Answer


2 Answers

It doesn't throw an error as it is pure C — and C doesn't know how to throw errors.


if you enter the objective world of Objective-C like

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

NSDecimalNumber *x = [i decimalNumberByDividingBy:o];

you will see

*** 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

But you actually can decide, what happens:

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

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

x will be NaN now.


But apple also provides C-types that are aware of calculation errors: 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;
}
like image 124
vikingosegundo Avatar answered Oct 16 '22 23:10

vikingosegundo


Why should it?

XCode gives you the warning Division by zero is undefined. That should be a big enough sign for you.


Note:

C# doesn't always throw an exception.

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


There's an amazing explanation in the C++ thread:

Dividing by zero is a logical error, a bug by the programmer. You shouldn't try to cope with it, you should debug and eliminate it.

Fix the hole in the wall rather than trying to hang a picture over it.

like image 44
Lord Zsolt Avatar answered Oct 17 '22 01:10

Lord Zsolt