обработка переполнения в Objective C

Я создаю шестнадцатеричный калькулятор в Objective-C. Моя проблема связана с длинными значениями, которые будут переполняться при умножении.

Когда я добавляю значения перед добавлением, я проверяю, что значение не будет переполнено, делая что-то вроде этого.

long long leftToAdd = LLONG_MAX - self.runningTotal;

if (self.selectedNumber <= leftToAdd) {
    self.runningTotal += self.selectedNumber;

} else {
    self.selectedNumber -= leftToAdd;   
    self.runningTotal = self.selectedNumber-1;

    self.overflowHasOccured = YES;   
}

если значение будет переполнено, оно берет значение переполнения (без фактического переполнения) и добавляет уведомление о переполнении. Я надеялся найти способ сделать то же самое, но для умножения, может ли кто-нибудь помочь с этим?

вот что у меня есть до сих пор.

// if - value would not overflow //
if (self.runningTotal > 0 && self.selectedNumber > 0 
    && LLONG_MAX/self.runningTotal >= self.selectedNumber) {

    self.runningTotal *= self.selectedNumber;

// else - handle overflow //
} else {


}

и как побочный вопрос, нужно ли мне делать аналогичную проверку на деление?


person user3474378    schedule 02.04.2014    source источник
comment
Вместо long long вы можете использовать NSDecimal или NSDecimalNumber, что даст вам 38 десятичных цифр.   -  person Martin R    schedule 02.04.2014


Ответы (1)


Вы можете проверить переполнение при умножении, следуя тому же шаблону, который вы используете для сложения - для более позднего вы используете вычитание для определения границы, для первого вы должны использовать деление:

long long canMultiplyBy = LLONG_MAX / self.runningTotal;

Во всех случаях, если вы поддерживаете числа со знаком, вы также должны учитывать недополнение. Для деления требуется проверка деления на ноль.

В библиотеке C есть функции для проверенной арифметики, lookup check_int64_mul для нахождения лота (все они описаны на той же странице руководства). Они будут эффективными и будут работать непосредственно с примитивными типами значений, как вы сейчас делаете.

Компилятор Clang также предоставляет некоторые проверенные встроенные арифметические функции, которые отличаются от функций библиотеки C тем, что возвращают индикацию bool и определяются для типов int, long и long long, а не int32 и int64. См. раздел Проверенные арифметические встроенные функции.

Также есть NSDecimal — тип значения, и NSDecimalNumber — тип объекта, надстроенный над первым. Они обеспечивают как повышенную точность, до 38 десятичных разрядов, так и контроль переполнения, потери значимости, деления на ноль и т. д. См. NSDecimalNumberBehaviors и NSDecimalNumberHandler.

ХТН

person CRD    schedule 02.04.2014